OpenCores
URL https://opencores.org/ocsvn/yahamm/yahamm/trunk

Subversion Repositories yahamm

[/] [yahamm/] [trunk/] [bench/] [vhdl/] [yahamm_tb1.vhd] - Diff between revs 4 and 5

Show entire file | Details | Blame | View Log

Rev 4 Rev 5
Line 1... Line 1...
 
-------------------------------------------------------------------------------
 
-- Yahamm IP core
 
--
 
-- This file is part of the Yahamm project
 
-- http://www.opencores.org/cores/yahamm
 
--
 
-- Description
 
-- A hamming encoder and decoder with single-error correcting and
 
-- double-error detecting capability. The message length can be configured
 
-- through a generic. Both the code generator matrix and the parity-check
 
-- matrix are computed in the VHDL itself.
 
--
 
-- To Do:
 
-- - write docs
 
--
 
-- Author:
 
-- - Nicola De Simone, ndesimone@opencores.org
 
--
 
-------------------------------------------------------------------------------
 
--
 
-- Copyright (C) 2017 Authors and OPENCORES.ORG
 
--
 
-- This source file may be used and distributed without
 
-- restriction provided that this copyright statement is not
 
-- removed from the file and that any derivative work contains
 
-- the original copyright notice and the associated disclaimer.
 
--
 
-- This source file is free software; you can redistribute it
 
-- and/or modify it under the terms of the GNU Lesser General
 
-- Public License as published by the Free Software Foundation;
 
-- either version 2.1 of the License, or (at your option) any
 
-- later version.
 
--
 
-- This source is distributed in the hope that it will be
 
-- useful, but WITHOUT ANY WARRANTY; without even the implied
 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
-- PURPOSE. See the GNU Lesser General Public License for more
 
-- details.
 
--
 
--- You should have received a copy of the GNU Lesser General
 
-- Public License along with this source; if not, download it
 
-- from http://www.opencores.org/lgpl.shtml
 
--
 
-------------------------------------------------------------------------------
 
 
 
-- Testbench with Single Error Corrected.
 
-- CORRECT true
 
-- EXTRA_PARITY_BIT 0
 
-- ONE_PARITY_BIT false
 
--
 
 
 
library std;
 
use std.env.all;
 
 
 
library ieee;
 
use ieee.std_logic_1164.all;
 
use ieee.math_real.all;
 
use ieee.numeric_std.all;
 
 
 
library yahamm;
 
use yahamm.yahamm_pkg.all;
 
use yahamm.matrix_pkg.all;
 
 
 
-------------------------------------------------------------------------------
 
 
 
entity yahamm_tb1 is
 
 
 
end entity yahamm_tb1;
 
 
 
-------------------------------------------------------------------------------
 
 
 
architecture tb of yahamm_tb1 is
 
 
 
  -- component ports
 
  signal chken, enc_en : std_logic := '1';
 
 
 
  -- Cannot use here MESSAGE_LENGTH > 30 otherwise datamax overflows.  This is
 
  -- just a limitation of this testbench.
 
  constant MESSAGE_LENGTH : natural := 30;
 
  constant DATAMAX        : natural := 2**MESSAGE_LENGTH - 1;
 
 
 
  constant CORRECT          : boolean := true;
 
  constant EXTRA_PARITY_BIT : natural := 0;
 
 
 
  constant ONE_PARITY_BIT : boolean := false;
 
 
 
  constant NPARITY_BITS : natural := calc_nparity_bits(MESSAGE_LENGTH, ONE_PARITY_BIT);
 
  constant BLOCK_LENGTH : natural := calc_block_length(MESSAGE_LENGTH, ONE_PARITY_BIT);
 
  constant ERROR_LEN    : natural := 16;
 
 
 
  constant NITERATIONS : natural := 1000;  -- number of iterations for each test
 
 
 
  signal data_enc_in, data_enc_out, data_enc_to_dec, data_dec_out : std_logic_vector(MESSAGE_LENGTH - 1 downto 0) := (others => '0');
 
  signal
 
    data_enc_in_q0,
 
    data_enc_in_q1,
 
    data_enc_in_q2 : std_logic_vector(data_enc_in'range);
 
  signal dec_cnt_clr                               : std_logic;  -- clear counters
 
  signal parity_enc_to_dec                         : std_logic_vector(NPARITY_BITS + EXTRA_PARITY_BIT - 1 downto 0);
 
  signal cnt_errors_corrected, cnt_errors_detected : std_logic_vector(ERROR_LEN - 1 downto 0);
 
 
 
  -- clock
 
  signal clk, rst : std_logic := '1';
 
 
 
  signal wrong_bit0_position, wrong_bit1_position, wrong_bit2_position : natural := 0;
 
 
 
begin  -- architecture tb
 
 
 
  --instance "yahamm_enc_1"
 
  yahamm_enc_1 : entity yahamm.yahamm_enc
 
    generic map (
 
      MESSAGE_LENGTH   => MESSAGE_LENGTH,
 
      EXTRA_PARITY_BIT => EXTRA_PARITY_BIT,
 
      ONE_PARITY_BIT   => ONE_PARITY_BIT)
 
    port map (
 
      clk_i    => clk,
 
      rst_i    => rst,
 
      en_i     => enc_en,
 
      data_i   => data_enc_in,
 
      data_o   => data_enc_out,
 
      parity_o => parity_enc_to_dec);
 
 
 
  yahamm_dec_1 : entity yahamm.yahamm_dec
 
    generic map (
 
      MESSAGE_LENGTH   => MESSAGE_LENGTH,
 
      CORRECT          => CORRECT,
 
      EXTRA_PARITY_BIT => EXTRA_PARITY_BIT,
 
      ONE_PARITY_BIT   => ONE_PARITY_BIT,
 
      ERROR_LEN        => ERROR_LEN)
 
    port map (
 
      clk_i                  => clk,
 
      rst_i                  => rst,
 
      cnt_clr_i              => dec_cnt_clr,
 
      en_i                   => enc_en,
 
      data_i                 => data_enc_to_dec,
 
      parity_i               => parity_enc_to_dec,
 
      data_o                 => data_dec_out,
 
      cnt_errors_corrected_o => cnt_errors_corrected,
 
      cnt_errors_detected_o  => cnt_errors_detected
 
      );
 
 
 
  -- clock generation
 
  clk <= not clk after 10 ns;
 
 
 
  -- purpose: delay inputs for later comparison with outputs.
 
  delays : process (clk, rst) is
 
  begin  -- process delays
 
    if rst = '1' then                   -- asynchronous reset (active high)
 
      data_enc_in_q0 <= (others => '0');
 
      data_enc_in_q1 <= (others => '0');
 
      data_enc_in_q2 <= (others => '0');
 
    elsif rising_edge(clk) then         -- rising clock edge
 
      data_enc_in_q0 <= data_enc_in;
 
      data_enc_in_q1 <= data_enc_in_q0;
 
      data_enc_in_q2 <= data_enc_in_q1;
 
    end if;
 
  end process delays;
 
 
 
  -- purpose: flit bits of the decoder inputs to produce errors.
 
  -- type   : combinational
 
  flip_bits_proc : process (data_enc_out, wrong_bit0_position, wrong_bit1_position) is
 
  begin  -- process flip_bits_proc
 
    data_enc_to_dec <= data_enc_out;
 
 
 
    if wrong_bit0_position > 0 then
 
      -- flip one bit
 
      data_enc_to_dec(wrong_bit0_position - 1) <= not data_enc_out(wrong_bit0_position - 1);
 
    end if;
 
 
 
    if wrong_bit1_position > 0 then
 
      -- flit another bit (can also randomly be the same one)
 
      data_enc_to_dec(wrong_bit1_position - 1) <= not data_enc_out(wrong_bit1_position - 1);
 
    end if;
 
  end process flip_bits_proc;
 
 
 
  -- waveform generation
 
  WaveGen_Proc : process
 
    variable random                                               : real;
 
    variable seed1, seed2                                         : positive := 1;
 
    variable test0_errors, test1_errors, test2_errors, test_clear : natural  := 0;
 
  begin
 
 
 
    dec_cnt_clr <= '0';
 
    rst         <= '1';
 
    wait until rising_edge(clk);
 
    rst         <= '0';
 
 
 
    -- TEST #0
 
    -- Without transmission errors.
 
    wrong_bit0_position <= 0;
 
    wrong_bit1_position <= 0;
 
    for itest in 0 to NITERATIONS-1 loop
 
      uniform(seed1, seed2, random);
 
      data_enc_in <= std_logic_vector(to_unsigned(integer(round(random*real(DATAMAX))), MESSAGE_LENGTH));
 
 
 
      wait until rising_edge(clk);
 
      assert data_enc_in_q2 = data_dec_out report "Test #0: Encoder input (" & to_hstring(data_enc_in_q2) & ") != decoder output (" & to_hstring(data_dec_out) & ")." severity error;
 
 
 
      if data_enc_in_q2 /= data_dec_out then
 
        test0_errors := test0_errors + 1;
 
      end if;
 
 
 
    end loop;
 
 
 
    wait until rising_edge(clk);
 
    wait until rising_edge(clk);
 
 
 
    assert to_integer(unsigned(cnt_errors_corrected)) = 0 report "Test #0: Unexpected cnt_errors_corrected " & integer'image(to_integer(unsigned(cnt_errors_corrected))) & ".  Should be 0." severity error;
 
    assert to_integer(unsigned(cnt_errors_detected)) = 0 report "Test #0: Unexpected cnt_errors_detected " & integer'image(to_integer(unsigned(cnt_errors_detected))) & ".  Should be 0." severity error;
 
 
 
    -- TEST #1
 
    -- Test the correction with 1 bit transmission error on a random bit
 
    wrong_bit1_position <= 0;
 
    for itest in 0 to NITERATIONS-1 loop
 
      uniform(seed1, seed2, random);
 
      data_enc_in <= std_logic_vector(to_unsigned(integer(round(random*real(DATAMAX))), MESSAGE_LENGTH));
 
 
 
      -- produce an error flipping a random bit in the encoder output.  0 means
 
      -- don't flip, so we have to add 1.
 
      uniform(seed1, seed2, random);
 
      wrong_bit0_position <= natural(trunc(random*real(MESSAGE_LENGTH))) + 1;
 
 
 
      assert data_enc_in_q2 = data_dec_out report "Test #1: Encoder input (" & to_hstring(data_enc_in_q2) & ") != decoder output (" & to_hstring(data_dec_out) & ")." severity error;
 
 
 
      if data_enc_in_q2 /= data_dec_out then
 
        test1_errors := test1_errors + 1;
 
      end if;
 
 
 
      wait until rising_edge(clk);
 
    end loop;
 
 
 
    wrong_bit0_position <= 0;
 
    wait until rising_edge(clk);
 
    wait until rising_edge(clk);
 
 
 
    assert to_integer(unsigned(cnt_errors_corrected)) = NITERATIONS report "Test #1: Unexpected cnt_errors_corrected " & integer'image(to_integer(unsigned(cnt_errors_corrected))) & ".  Should be " & integer'image(NITERATIONS) severity error;
 
    assert to_integer(unsigned(cnt_errors_detected)) = 0 report "Test #1: Unexpected cnt_errors_detected " & integer'image(to_integer(unsigned(cnt_errors_detected))) & ".  Should be 0." severity error;
 
 
 
    -- clear decoder counters
 
    dec_cnt_clr <= '1';
 
    wait until rising_edge(clk);
 
    dec_cnt_clr <= '0';
 
    wait until rising_edge(clk);
 
 
 
    -- check the clear
 
    if to_integer(unsigned(cnt_errors_corrected)) /= 0 then
 
      report "Unexpected cnt_errors_corrected " & integer'image(to_integer(unsigned(cnt_errors_corrected))) & ".  Should be 0 after clear." severity error;
 
      test_clear := 1;
 
    end if;
 
 
 
    -- TEST #2
 
    -- Test the non working correction with 2 bit transmission error.
 
    for itest in 0 to NITERATIONS-1 loop
 
      uniform(seed1, seed2, random);
 
      data_enc_in <= std_logic_vector(to_unsigned(integer(round(random*real(DATAMAX))), MESSAGE_LENGTH));
 
 
 
      -- produce an error flipping a random bit in the encoder output.  0 means
 
      -- don't flip, so we have to add 1.
 
      uniform(seed1, seed2, random);
 
      wrong_bit0_position <= natural(trunc(random*real(MESSAGE_LENGTH))) + 1;
 
      uniform(seed1, seed2, random);
 
      wrong_bit1_position <= natural(trunc(random*real(MESSAGE_LENGTH))) + 1;
 
 
 
      if data_enc_in_q2 /= data_dec_out then
 
        test2_errors := test2_errors + 1;
 
      end if;
 
 
 
      wait until rising_edge(clk);
 
    end loop;
 
 
 
    assert test0_errors = 0 and test1_errors = 0 and test2_errors > 0 and test_clear = 0 report "Test #2: TB1 unsuccessful." severity failure;
 
 
 
    assert false report "OK" severity note;
 
    stop(0);
 
 
 
  end process WaveGen_Proc;
 
 
 
 
 
end architecture tb;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.