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 4

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

powered by: WebSVN 2.1.0

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