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

Subversion Repositories yahamm

[/] [yahamm/] [trunk/] [bench/] [vhdl/] [yahamm_tb2.vhd] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 ndesimone
-------------------------------------------------------------------------------
2
-- Yahamm IP core
3
--
4
-- This file is part of the Yahamm project
5
-- http://www.opencores.org/cores/yahamm
6
--
7
-- Description
8
-- A hamming encoder and decoder with single-error correcting and
9
-- double-error detecting capability. The message length can be configured
10
-- through a generic. Both the code generator matrix and the parity-check
11
-- matrix are computed in the VHDL itself.
12
--
13
-- To Do:
14
-- - write docs
15
--
16
-- Author:
17
-- - Nicola De Simone, ndesimone@opencores.org
18
--
19
-------------------------------------------------------------------------------
20
--
21
-- Copyright (C) 2017 Authors and OPENCORES.ORG
22
--
23
-- This source file may be used and distributed without
24
-- restriction provided that this copyright statement is not
25
-- removed from the file and that any derivative work contains
26
-- the original copyright notice and the associated disclaimer.
27
--
28
-- This source file is free software; you can redistribute it
29
-- and/or modify it under the terms of the GNU Lesser General
30
-- Public License as published by the Free Software Foundation;
31
-- either version 2.1 of the License, or (at your option) any
32
-- later version.
33
--
34
-- This source is distributed in the hope that it will be
35
-- useful, but WITHOUT ANY WARRANTY; without even the implied
36
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
37
-- PURPOSE. See the GNU Lesser General Public License for more
38
-- details.
39
--
40
--- You should have received a copy of the GNU Lesser General
41
-- Public License along with this source; if not, download it
42
-- from http://www.opencores.org/lgpl.shtml
43
--
44
-------------------------------------------------------------------------------
45
 
46
-- Testbench with Single Error Corrected, Double Error Detected
47
-- CORRECT true
48
-- EXTRA_PARITY_BIT 1
49
-- ONE_PARITY_BIT false
50
--
51
 
52
library std;
53
use std.env.all;
54
 
55
library ieee;
56
use ieee.std_logic_1164.all;
57
use ieee.math_real.all;
58
use ieee.numeric_std.all;
59
 
60
library yahamm;
61
use yahamm.yahamm_pkg.all;
62
use yahamm.matrix_pkg.all;
63
 
64
-------------------------------------------------------------------------------
65
 
66
entity yahamm_tb2 is
67
 
68
end entity yahamm_tb2;
69
 
70
-------------------------------------------------------------------------------
71
 
72
architecture tb of yahamm_tb2 is
73
 
74
  -- component ports
75 5 ndesimone
  signal chken, enc_en : std_logic := '1';
76 4 ndesimone
 
77
  -- Cannot use here MESSAGE_LENGTH > 30 otherwise datamax overflows.  This is
78
  -- just a limitation of this testbench.
79
  constant MESSAGE_LENGTH : natural := 3;
80 5 ndesimone
  constant DATAMAX        : natural := 2**MESSAGE_LENGTH - 1;
81 4 ndesimone
 
82 5 ndesimone
  constant CORRECT          : boolean := true;
83 4 ndesimone
  constant EXTRA_PARITY_BIT : natural := 1;
84
 
85
  constant ONE_PARITY_BIT : boolean := false;
86 5 ndesimone
 
87 4 ndesimone
  constant NPARITY_BITS : natural := calc_nparity_bits(MESSAGE_LENGTH, ONE_PARITY_BIT);
88
  constant BLOCK_LENGTH : natural := calc_block_length(MESSAGE_LENGTH, ONE_PARITY_BIT);
89 5 ndesimone
  constant ERROR_LEN    : natural := 16;
90 4 ndesimone
 
91
  constant NITERATIONS : natural := 1000;  -- number of iterations for each test
92 5 ndesimone
 
93 4 ndesimone
  signal data_enc_in, data_enc_out, data_enc_to_dec, data_dec_out : std_logic_vector(MESSAGE_LENGTH - 1 downto 0) := (others => '0');
94
  signal
95
    data_enc_in_q0,
96
    data_enc_in_q1,
97
    data_enc_in_q2 : std_logic_vector(data_enc_in'range);
98 5 ndesimone
  signal dec_cnt_clr                               : std_logic;  -- clear counters
99
  signal parity_enc_out, parity_enc_to_dec         : std_logic_vector(NPARITY_BITS + EXTRA_PARITY_BIT - 1 downto 0);
100
  signal cnt_errors_corrected, cnt_errors_detected : std_logic_vector(ERROR_LEN - 1 downto 0);
101 4 ndesimone
 
102
  -- clock
103
  signal clk, rst : std_logic := '1';
104
 
105 5 ndesimone
  signal wrong_bit0_data_position, wrong_bit1_data_position     : natural := 0;
106 4 ndesimone
  signal wrong_bit0_parity_position, wrong_bit1_parity_position : natural := 0;
107 5 ndesimone
 
108 4 ndesimone
begin  -- architecture tb
109
 
110 5 ndesimone
  --instance "yahamm_enc_1"
111
  yahamm_enc_1 : entity yahamm.yahamm_enc
112 4 ndesimone
    generic map (
113 5 ndesimone
      MESSAGE_LENGTH   => MESSAGE_LENGTH,
114
      EXTRA_PARITY_BIT => EXTRA_PARITY_BIT,
115
      ONE_PARITY_BIT   => ONE_PARITY_BIT)
116 4 ndesimone
    port map (
117 5 ndesimone
      clk_i    => clk,
118
      rst_i    => rst,
119
      en_i     => enc_en,
120
      data_i   => data_enc_in,
121
      data_o   => data_enc_out,
122
      parity_o => parity_enc_out);
123 4 ndesimone
 
124 5 ndesimone
  yahamm_dec_1 : entity yahamm.yahamm_dec
125 4 ndesimone
    generic map (
126 5 ndesimone
      MESSAGE_LENGTH   => MESSAGE_LENGTH,
127
      CORRECT          => CORRECT,
128
      EXTRA_PARITY_BIT => EXTRA_PARITY_BIT,
129
      ONE_PARITY_BIT   => ONE_PARITY_BIT,
130
      ERROR_LEN        => ERROR_LEN)
131 4 ndesimone
    port map (
132 5 ndesimone
      clk_i                  => clk,
133
      rst_i                  => rst,
134
      cnt_clr_i              => dec_cnt_clr,
135
      en_i                   => enc_en,
136
      data_i                 => data_enc_to_dec,
137
      parity_i               => parity_enc_to_dec,
138
      data_o                 => data_dec_out,
139
      cnt_errors_corrected_o => cnt_errors_corrected,
140
      cnt_errors_detected_o  => cnt_errors_detected
141 4 ndesimone
      );
142 5 ndesimone
 
143 4 ndesimone
  -- clock generation
144
  clk <= not clk after 10 ns;
145
 
146
  -- purpose: delay inputs for later comparison with outputs.
147 5 ndesimone
  delays : process (clk, rst) is
148
  begin  -- process delays
149
    if rst = '1' then                   -- asynchronous reset (active high)
150 4 ndesimone
      data_enc_in_q0 <= (others => '0');
151
      data_enc_in_q1 <= (others => '0');
152
      data_enc_in_q2 <= (others => '0');
153 5 ndesimone
    elsif rising_edge(clk) then         -- rising clock edge
154 4 ndesimone
      data_enc_in_q0 <= data_enc_in;
155
      data_enc_in_q1 <= data_enc_in_q0;
156
      data_enc_in_q2 <= data_enc_in_q1;
157
    end if;
158
  end process delays;
159
 
160
  -- purpose: flit bits of the decoder inputs to produce errors.
161
  -- type   : combinational
162 5 ndesimone
  flip_bits_proc : process (data_enc_out,
163
                            wrong_bit0_data_position, wrong_bit1_data_position,
164
                            wrong_bit0_parity_position, wrong_bit1_parity_position) is
165
  begin  -- process flip_bits_proc
166
    data_enc_to_dec   <= data_enc_out;
167 4 ndesimone
    parity_enc_to_dec <= parity_enc_out;
168 5 ndesimone
 
169 4 ndesimone
    if wrong_bit0_data_position > 0 then
170
      -- flip one bit
171
      data_enc_to_dec(wrong_bit0_data_position - 1) <= not data_enc_out(wrong_bit0_data_position - 1);
172
    end if;
173 5 ndesimone
 
174 4 ndesimone
    if wrong_bit1_data_position > 0 then
175
      -- flip another bit (it can also randomly be the same one)
176
      data_enc_to_dec(wrong_bit1_data_position - 1) <= not data_enc_out(wrong_bit1_data_position - 1);
177
    end if;
178 5 ndesimone
 
179 4 ndesimone
    if wrong_bit0_parity_position > 0 then
180
      -- flip one bit
181
      parity_enc_to_dec(wrong_bit0_parity_position - 1) <= not parity_enc_out(wrong_bit0_parity_position - 1);
182
    end if;
183 5 ndesimone
 
184 4 ndesimone
    if wrong_bit1_parity_position > 0 then
185
      -- flip another bit (it can also randomly be the same one)
186
      parity_enc_to_dec(wrong_bit1_parity_position - 1) <= not parity_enc_out(wrong_bit1_parity_position - 1);
187
    end if;
188 5 ndesimone
 
189 4 ndesimone
  end process flip_bits_proc;
190 5 ndesimone
 
191 4 ndesimone
  -- waveform generation
192 5 ndesimone
  WaveGen_Proc : process
193
    variable random                                               : real;
194
    variable seed1, seed2                                         : positive := 1;
195
    variable test0_errors, test1_errors, test2_errors, test_clear : natural  := 0;
196 4 ndesimone
  begin
197
 
198
    dec_cnt_clr <= '0';
199 5 ndesimone
    rst         <= '1';
200 4 ndesimone
    wait until rising_edge(clk);
201 5 ndesimone
    rst         <= '0';
202 4 ndesimone
 
203
    -- TEST #0
204
    -- Without transmission errors.
205
    wrong_bit0_data_position <= 0;
206
    wrong_bit1_data_position <= 0;
207
    for itest in 0 to NITERATIONS-1 loop
208
      uniform(seed1, seed2, random);
209
      data_enc_in <= std_logic_vector(to_unsigned(integer(round(random*real(DATAMAX))), MESSAGE_LENGTH));
210 5 ndesimone
 
211
      wait until rising_edge(clk);
212 4 ndesimone
      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;
213
 
214
      if data_enc_in_q2 /= data_dec_out then
215 5 ndesimone
        test0_errors := test0_errors + 1;
216 4 ndesimone
      end if;
217 5 ndesimone
 
218 4 ndesimone
    end loop;
219 5 ndesimone
 
220 4 ndesimone
    wait until rising_edge(clk);
221
    wait until rising_edge(clk);
222
 
223
    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;
224
    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;
225
 
226
    -- TEST #1
227
    -- Test the correction with 1 bit transmission error on a random bit
228
    wrong_bit1_data_position <= 0;
229
    for itest in 0 to NITERATIONS-1 loop
230
      uniform(seed1, seed2, random);
231
      data_enc_in <= std_logic_vector(to_unsigned(integer(round(random*real(DATAMAX))), MESSAGE_LENGTH));
232 5 ndesimone
 
233
      -- produce an error flipping a random bit in the encoder output.  0 means
234 4 ndesimone
      -- don't flip, so we have to add 1.
235
      uniform(seed1, seed2, random);
236
      wrong_bit0_data_position <= natural(trunc(random*real(MESSAGE_LENGTH))) + 1;
237
 
238
      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;
239
 
240
      if data_enc_in_q2 /= data_dec_out then
241 5 ndesimone
        test1_errors := test1_errors + 1;
242 4 ndesimone
      end if;
243 5 ndesimone
 
244 4 ndesimone
      wait until rising_edge(clk);
245
    end loop;
246
 
247 5 ndesimone
    wrong_bit0_data_position <= 0;
248 4 ndesimone
    wait until rising_edge(clk);
249
    wait until rising_edge(clk);
250
 
251
    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;
252
    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;
253
 
254
    -- TEST #2
255
    -- Test the non working correction with 2 bit transmission error.
256
    for itest in 0 to NITERATIONS-1 loop
257
      uniform(seed1, seed2, random);
258
      data_enc_in <= std_logic_vector(to_unsigned(integer(round(random*real(DATAMAX))), MESSAGE_LENGTH));
259 5 ndesimone
 
260
      -- produce an error flipping a random bit in the encoder output.  0 means
261 4 ndesimone
      -- don't flip, so we have to add 1.
262
      uniform(seed1, seed2, random);
263
      wrong_bit0_data_position <= natural(trunc(random*real(MESSAGE_LENGTH))) + 1;
264
      uniform(seed1, seed2, random);
265
      wrong_bit1_data_position <= natural(trunc(random*real(MESSAGE_LENGTH))) + 1;
266
 
267
      if data_enc_in_q2 /= data_dec_out then
268 5 ndesimone
        test2_errors := test2_errors + 1;
269 4 ndesimone
      end if;
270 5 ndesimone
 
271 4 ndesimone
      wait until rising_edge(clk);
272
    end loop;
273
 
274 5 ndesimone
    wrong_bit0_data_position <= 0;
275
    wrong_bit1_data_position <= 0;
276 4 ndesimone
    wait until rising_edge(clk);
277
    wait until rising_edge(clk);
278 5 ndesimone
 
279 4 ndesimone
    assert to_integer(unsigned(cnt_errors_corrected)) > 0 report "Test #2: Unexpected cnt_errors_corrected " & integer'image(to_integer(unsigned(cnt_errors_corrected))) & ".  Should be > 0." severity error;
280
    assert to_integer(unsigned(cnt_errors_detected)) > 0 report "Test #2: Unexpected cnt_errors_detected " & integer'image(to_integer(unsigned(cnt_errors_detected))) & ".  Should be > 0." severity error;
281 5 ndesimone
 
282 4 ndesimone
    -- clear decoder counters
283
    dec_cnt_clr <= '1';
284
    wait until rising_edge(clk);
285
    dec_cnt_clr <= '0';
286
    wait until rising_edge(clk);
287 5 ndesimone
 
288 4 ndesimone
    -- check the clear
289
    if to_integer(unsigned(cnt_errors_corrected)) /= 0 then
290
      report "Unexpected cnt_errors_corrected " & integer'image(to_integer(unsigned(cnt_errors_corrected))) & ".  Should be 0 after clear." severity error;
291
      test_clear := 1;
292
    end if;
293
    if to_integer(unsigned(cnt_errors_detected)) /= 0 then
294
      report "Unexpected cnt_errors_detected " & integer'image(to_integer(unsigned(cnt_errors_detected))) & ".  Should be 0 after clear." severity error;
295
      test_clear := 1;
296
    end if;
297 5 ndesimone
 
298 4 ndesimone
    assert test0_errors = 0 and test1_errors = 0 and test2_errors > 0 and test_clear = 0 report "TB2 unsuccessful." severity failure;
299
 
300 5 ndesimone
    assert false report "OK" severity note;
301 4 ndesimone
    stop(0);
302
 
303
  end process WaveGen_Proc;
304
 
305 5 ndesimone
 
306 4 ndesimone
end architecture tb;

powered by: WebSVN 2.1.0

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