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

Subversion Repositories iicmb

[/] [iicmb/] [trunk/] [src_tb/] [iicmb_m_wb_tb.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sshuv2
 
2
--==============================================================================
3
--                                                                             |
4
--    Project: IIC Multiple Bus Controller (IICMB)                             |
5
--                                                                             |
6
--    Module:  Testbench for 'iicmb_m_wb'.                                     |
7
--    Version:                                                                 |
8
--             1.0,   April 29, 2016                                           |
9 5 sshuv2
--             1.1,   May   10, 2016 Changed i2c_slave_model instance          |
10
--                                   parameter interface                       |
11 2 sshuv2
--                                                                             |
12
--    Author:  Sergey Shuvalkin, (sshuv2@opencores.org)                        |
13
--                                                                             |
14
--==============================================================================
15
--==============================================================================
16
-- Copyright (c) 2016, Sergey Shuvalkin                                        |
17
-- All rights reserved.                                                        |
18
--                                                                             |
19
-- Redistribution and use in source and binary forms, with or without          |
20
-- modification, are permitted provided that the following conditions are met: |
21
--                                                                             |
22
-- 1. Redistributions of source code must retain the above copyright notice,   |
23
--    this list of conditions and the following disclaimer.                    |
24
-- 2. Redistributions in binary form must reproduce the above copyright        |
25
--    notice, this list of conditions and the following disclaimer in the      |
26
--    documentation and/or other materials provided with the distribution.     |
27
--                                                                             |
28
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
29
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   |
30
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  |
31
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE    |
32
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         |
33
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        |
34
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    |
35
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     |
36
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     |
37
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  |
38
-- POSSIBILITY OF SUCH DAMAGE.                                                 |
39
--==============================================================================
40
 
41
 
42
library ieee;
43
use ieee.std_logic_1164.all;
44
use ieee.numeric_std.all;
45
 
46
library iicmb;
47
use iicmb.iicmb_pkg.all;
48
 
49
use work.test.all;
50
 
51
 
52
--==============================================================================
53
entity iicmb_m_wb_tb is
54
end entity iicmb_m_wb_tb;
55
--==============================================================================
56
 
57
--==============================================================================
58
architecture beh of iicmb_m_wb_tb is
59
 
60
  constant c_f_clk   : real      := 100000.0; -- in kHz
61
  constant c_f_scl_0 : real      :=    100.0; -- in kHz
62
  constant c_f_scl_1 : real      :=    100.0; -- in kHz
63
  constant c_f_scl_2 : real      :=    100.0; -- in kHz
64
  constant c_f_scl_3 : real      :=    100.0; -- in kHz
65
  constant c_p_clk   : time      := integer(1000000000.0/c_f_clk) * 1 ps;
66
 
67
  constant c_bus_num : positive  := 4;
68
 
69
  ------------------------------------------------------------------------------
70
  component iicmb_m_wb is
71
    generic
72
    (
73
      g_bus_num   :       positive range 1 to 16 := 1;
74
      g_f_clk     :       real                   := 100000.0;
75
      g_f_scl_0   :       real                   :=    100.0;
76
      g_f_scl_1   :       real                   :=    100.0;
77
      g_f_scl_2   :       real                   :=    100.0;
78
      g_f_scl_3   :       real                   :=    100.0;
79
      g_f_scl_4   :       real                   :=    100.0;
80
      g_f_scl_5   :       real                   :=    100.0;
81
      g_f_scl_6   :       real                   :=    100.0;
82
      g_f_scl_7   :       real                   :=    100.0;
83
      g_f_scl_8   :       real                   :=    100.0;
84
      g_f_scl_9   :       real                   :=    100.0;
85
      g_f_scl_a   :       real                   :=    100.0;
86
      g_f_scl_b   :       real                   :=    100.0;
87
      g_f_scl_c   :       real                   :=    100.0;
88
      g_f_scl_d   :       real                   :=    100.0;
89
      g_f_scl_e   :       real                   :=    100.0;
90
      g_f_scl_f   :       real                   :=    100.0
91
    );
92
    port
93
    (
94
      clk_i       : in    std_logic;
95
      rst_i       : in    std_logic;
96
      cyc_i       : in    std_logic;
97
      stb_i       : in    std_logic;
98
      ack_o       :   out std_logic;
99
      adr_i       : in    std_logic_vector(1 downto 0);
100
      we_i        : in    std_logic;
101
      dat_i       : in    std_logic_vector(7 downto 0);
102
      dat_o       :   out std_logic_vector(7 downto 0);
103
      irq         :   out std_logic;
104
      scl_i       : in    std_logic_vector(0 to g_bus_num - 1);
105
      sda_i       : in    std_logic_vector(0 to g_bus_num - 1);
106
      scl_o       :   out std_logic_vector(0 to g_bus_num - 1);
107
      sda_o       :   out std_logic_vector(0 to g_bus_num - 1)
108
    );
109
  end component iicmb_m_wb;
110
  ------------------------------------------------------------------------------
111
 
112
  ------------------------------------------------------------------------------
113
  component wire_mdl is
114
    generic
115
    (
116
      g_resistance_0       :       real       := 1.0; -- In Ohms
117
      g_resistance_1       :       real       := 1.0; -- In Ohms
118
      g_capacitance        :       real       := 1.0; -- In pF
119
      g_initial_level      :       bit        := '0'
120
    );
121
    port
122
    (
123
      sig_in               : in    bit;
124
      sig_out              :   out real;
125
      sig_out_l            :   out bit
126
    );
127
  end component wire_mdl;
128
  ------------------------------------------------------------------------------
129
 
130
  ------------------------------------------------------------------------------
131
  component i2c_slave_model is
132
    generic
133
    (
134 4 sshuv2
      I2C_ADR : integer
135 2 sshuv2
    );
136
    port
137
    (
138
      scl     : inout std_logic;
139
      sda     : inout std_logic
140
    );
141
  end component i2c_slave_model;
142
  ------------------------------------------------------------------------------
143
 
144
  ------------------------------------------------------------------------------
145
  function get_slave_addr(n : natural) return std_logic_vector is
146
    variable ret : std_logic_vector(6 downto 0);
147
  begin
148
    ret := "010" & std_logic_vector(to_unsigned(n, 4));
149
    return ret;
150
  end function get_slave_addr;
151
  ------------------------------------------------------------------------------
152
 
153
  signal   clk_i         : std_logic := '0';
154
  signal   rst_i         : std_logic := '1';
155
  signal   cyc_i         : std_logic := '0';
156
  signal   stb_i         : std_logic := '0';
157
  signal   ack_o         : std_logic;
158
  signal   adr_i         : std_logic_vector(1 downto 0) := "00";
159
  signal   we_i          : std_logic := '0';
160
  signal   dat_i         : std_logic_vector(7 downto 0) := "00000000";
161
  signal   dat_o         : std_logic_vector(7 downto 0);
162
 
163
  signal   scl_o         : std_logic_vector(0 to c_bus_num - 1) := (others => '1');
164
  signal   scl           : std_logic_vector(0 to c_bus_num - 1) := (others => 'H');
165
  signal   sda_o         : std_logic_vector(0 to c_bus_num - 1) := (others => '1');
166
  signal   sda           : std_logic_vector(0 to c_bus_num - 1) := (others => 'H');
167
 
168
  type real_vector is array (natural range <>) of real;
169
  signal   scl_real      : real_vector(0 to c_bus_num - 1);
170
  signal   sda_real      : real_vector(0 to c_bus_num - 1);
171
  signal   scl_quant     : bit_vector(0 to c_bus_num - 1);
172
  signal   sda_quant     : bit_vector(0 to c_bus_num - 1);
173
  signal   scl_nquant    : bit_vector(0 to c_bus_num - 1) := (others => '1');
174
  signal   sda_nquant    : bit_vector(0 to c_bus_num - 1) := (others => '1');
175
  signal   irq           : std_logic;
176
 
177
  ---- Byte-wide commands:
178
  constant wb_m_set_bus  : std_logic_vector(7 downto 0) := "00000" & mcmd_set_bus;
179
  constant wb_m_write    : std_logic_vector(7 downto 0) := "00000" & mcmd_write;
180
  constant wb_m_read_ack : std_logic_vector(7 downto 0) := "00000" & mcmd_read_ack;
181
  constant wb_m_read_nak : std_logic_vector(7 downto 0) := "00000" & mcmd_read_nak;
182
  constant wb_m_start    : std_logic_vector(7 downto 0) := "00000" & mcmd_start;
183
  constant wb_m_stop     : std_logic_vector(7 downto 0) := "00000" & mcmd_stop;
184
  constant wb_m_wait     : std_logic_vector(7 downto 0) := "00000" & mcmd_wait;
185
 
186
begin
187
 
188
  clk_i <= not(clk_i) after c_p_clk / 2;
189
  rst_i <= '1', '0' after 113 ns;
190
 
191
  ------------------------------------------------------------------------------
192
  -- Wishbone bus activity process:
193
  process
194
    ----------------------------------------------------------------------------
195
    procedure wb_write(addr : in std_logic_vector(1 downto 0); data : in std_logic_vector(7 downto 0)) is
196
    begin
197
      cyc_i   <= '1';
198
      stb_i   <= '1';
199
      adr_i   <= addr;
200
      we_i    <= '1';
201
      dat_i   <= data;
202
      wait until rising_edge(clk_i)and(ack_o = '1');
203
      cyc_i   <= '0';
204
      stb_i   <= '0';
205
      print_string("Wishbone Write: 0x" & to_string(addr, "X", 2) & " : " & "0x" & to_string(data, "X", 2) & newline);
206
    end procedure wb_write;
207
    ----------------------------------------------------------------------------
208
    ----------------------------------------------------------------------------
209
    procedure wb_read(addr : in std_logic_vector(1 downto 0); data : out std_logic_vector(7 downto 0)) is
210
    begin
211
      cyc_i   <= '1';
212
      stb_i   <= '1';
213
      adr_i   <= addr;
214
      we_i    <= '0';
215
      wait until rising_edge(clk_i)and(ack_o = '1');
216
      data    := dat_o;
217
      cyc_i   <= '0';
218
      stb_i   <= '0';
219
      print_string("Wishbone Read : 0x" & to_string(addr, "X", 2) & " : " & "0x" & to_string(dat_o, "X", 2) & newline);
220
    end procedure wb_read;
221
    ----------------------------------------------------------------------------
222
    ----------------------------------------------------------------------------
223
    procedure wb_wait(n : in positive) is
224
    begin
225
      print_string("Wishbone Waiting for " & integer'image(n) & " cycles." & newline);
226
      cyc_i   <= '0';
227
      stb_i   <= '0';
228
      for i in 0 to n - 1 loop
229
        wait until rising_edge(clk_i);
230
      end loop;
231
    end procedure wb_wait;
232
    ----------------------------------------------------------------------------
233
    ----------------------------------------------------------------------------
234
    procedure wb_halt is
235
    begin
236
      print_string("Wishbone Halted" & newline);
237
      cyc_i   <= '0';
238
      stb_i   <= '0';
239
      wait;
240
    end procedure wb_halt;
241
    ----------------------------------------------------------------------------
242
    procedure i2c_write_byte(slave_addr : in std_logic_vector(6 downto 0); addr : in std_logic_vector(7 downto 0); data : in std_logic_vector(7 downto 0)) is
243
      variable v_tmp : std_logic_vector(7 downto 0);
244
    begin
245
      wb_write("10", wb_m_start);
246
      wait until rising_edge(clk_i)and(irq = '1');
247
      wb_read("10", v_tmp);
248
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
249
      --
250
      wb_write("01", slave_addr & "0");
251
      wb_write("10", wb_m_write);
252
      wait until rising_edge(clk_i)and(irq = '1');
253
      wb_read("10", v_tmp);
254
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
255
      --
256
      wb_write("01", addr);
257
      wb_write("10", wb_m_write);
258
      wait until rising_edge(clk_i)and(irq = '1');
259
      wb_read("10", v_tmp);
260
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
261
      --
262
      wb_write("01", data);
263
      wb_write("10", wb_m_write);
264
      wait until rising_edge(clk_i)and(irq = '1');
265
      wb_read("10", v_tmp);
266
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
267
      --
268
      wb_write("10", wb_m_stop);
269
      wait until rising_edge(clk_i)and(irq = '1');
270
      wb_read("10", v_tmp);
271
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
272
    end procedure i2c_write_byte;
273
    ----------------------------------------------------------------------------
274
    ----------------------------------------------------------------------------
275
    procedure i2c_read_byte(slave_addr : in std_logic_vector(6 downto 0); addr : in std_logic_vector(7 downto 0); data : out std_logic_vector(7 downto 0)) is
276
      variable v_tmp : std_logic_vector(7 downto 0);
277
    begin
278
      wb_write("10", wb_m_start);
279
      wait until rising_edge(clk_i)and(irq = '1');
280
      wb_read("10", v_tmp);
281
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
282
      --
283
      wb_write("01", slave_addr & "0");
284
      wb_write("10", wb_m_write);
285
      wait until rising_edge(clk_i)and(irq = '1');
286
      wb_read("10", v_tmp);
287
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
288
      --
289
      wb_write("01", addr);
290
      wb_write("10", wb_m_write);
291
      wait until rising_edge(clk_i)and(irq = '1');
292
      wb_read("10", v_tmp);
293
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
294
      --
295
      wb_write("10", wb_m_start);
296
      wait until rising_edge(clk_i)and(irq = '1');
297
      wb_read("10", v_tmp);
298
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
299
      --
300
      wb_write("01", slave_addr & "1");
301
      wb_write("10", wb_m_write);
302
      wait until rising_edge(clk_i)and(irq = '1');
303
      wb_read("10", v_tmp);
304
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
305
      --
306
      wb_write("10", wb_m_read_nak);
307
      wait until rising_edge(clk_i)and(irq = '1');
308
      wb_read("10", v_tmp);
309
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
310
      wb_read("01", data);
311
      --
312
      wb_write("10", wb_m_stop);
313
      wait until rising_edge(clk_i)and(irq = '1');
314
      wb_read("10", v_tmp);
315
      assert (v_tmp(7) = '1') report "Something gone wrong" severity error;
316
    end procedure i2c_read_byte;
317
    ----------------------------------------------------------------------------
318
    variable v_data : std_logic_vector(7 downto 0);
319
  begin
320
    -- Initial delay:
321
    wb_wait(100);
322
 
323
    --
324
    wb_read("00", v_data);
325
    wb_read("01", v_data);
326
    wb_read("10", v_data);
327
    wb_wait(1);
328
    wb_read("11", v_data);
329
    --
330
    wb_wait(10);
331
    -- Enable controller and interrupts
332
    wb_write("00", "11000000");
333
    wb_read("00", v_data);
334
    --
335
    -- Select Bus #1
336
    wb_wait(10);
337
    wb_write("01", "00000001");
338
    wb_write("10", wb_m_set_bus);
339
    wb_wait(1);
340
    wb_read("10", v_data);
341
    --
342
 
343
    --
344
    wb_wait(10);
345
    i2c_write_byte(get_slave_addr(1), x"00", x"4A");
346
    i2c_write_byte(get_slave_addr(1), x"01", x"67");
347
    --
348
 
349
    --
350
    wb_wait(10);
351
    i2c_read_byte(get_slave_addr(1), x"00", v_data);
352
    print_string("Data read: " & to_string(v_data, "X", 2) & newline);
353
    i2c_read_byte(get_slave_addr(1), x"01", v_data);
354
    print_string("Data read: " & to_string(v_data, "X", 2) & newline);
355
    --
356
 
357
    -- Halt bus activity
358
    wb_halt;
359
  end process;
360
  ------------------------------------------------------------------------------
361
 
362
  ------------------------------------------------------------------------------
363
  dut : iicmb_m_wb
364
    generic map
365
    (
366
      g_bus_num   => c_bus_num,
367
      g_f_clk     => c_f_clk,
368
      g_f_scl_0   => c_f_scl_0,
369
      g_f_scl_1   => c_f_scl_1,
370
      g_f_scl_2   => c_f_scl_2,
371
      g_f_scl_3   => c_f_scl_3
372
    )
373
    port map
374
    (
375
      clk_i       => clk_i,
376
      rst_i       => rst_i,
377
      cyc_i       => cyc_i,
378
      stb_i       => stb_i,
379
      ack_o       => ack_o,
380
      adr_i       => adr_i,
381
      we_i        => we_i,
382
      dat_i       => dat_i,
383
      dat_o       => dat_o,
384
      irq         => irq,
385
      scl_i       => to_stdlogicvector(scl_quant),
386
      sda_i       => to_stdlogicvector(sda_quant),
387
      scl_o       => scl_o,
388
      sda_o       => sda_o
389
    );
390
  ------------------------------------------------------------------------------
391
 
392
  --****************************************************************************
393
  bus_gen:
394
  for i in 0 to c_bus_num - 1 generate
395
    scl(i) <= '0' when (scl_o(i) = '0') else 'Z';
396
    sda(i) <= '0' when (sda_o(i) = '0') else 'Z';
397
 
398
    ----------------------------------------------------------------------------
399
    wire_mdl_inst_0 : wire_mdl
400
      generic map
401
      (
402
        g_resistance_0       => 40.0,
403
        g_resistance_1       => 4000.0,
404
        g_capacitance        => 200.0, -- In pF
405
        g_initial_level      => '1'
406
      )
407
      port map
408
      (
409
        sig_in               => scl_nquant(i),
410
        sig_out              => scl_real(i),
411
        sig_out_l            => scl_quant(i)
412
      );
413
    ----------------------------------------------------------------------------
414
 
415
    ----------------------------------------------------------------------------
416
    wire_mdl_inst_1 : wire_mdl
417
      generic map
418
      (
419
        g_resistance_0       => 40.0,
420
        g_resistance_1       => 4000.0,
421
        g_capacitance        => 200.0, -- In pF
422
        g_initial_level      => '1'
423
      )
424
      port map
425
      (
426
        sig_in               => sda_nquant(i),
427
        sig_out              => sda_real(i),
428
        sig_out_l            => sda_quant(i)
429
      );
430
    ----------------------------------------------------------------------------
431
 
432
    ----------------------------------------------------------------------------
433
    i2c_slave_model_inst0 : i2c_slave_model
434
      generic map
435
      (
436 4 sshuv2
        I2C_ADR => to_integer(unsigned(get_slave_addr(i)))
437 2 sshuv2
      )
438
      port map
439
      (
440
        scl     => scl(i),
441
        sda     => sda(i)
442
      );
443
    ----------------------------------------------------------------------------
444
  end generate bus_gen;
445
  --****************************************************************************
446
 
447
  scl <= (others => 'H'); -- Pull up
448
  sda <= (others => 'H'); -- Pull up
449
 
450
  scl_nquant <= to_bitvector(to_x01(scl));
451
  sda_nquant <= to_bitvector(to_x01(sda));
452
 
453
end architecture beh;
454
--==============================================================================
455
 

powered by: WebSVN 2.1.0

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