aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/issue1597/proc_pkg.vhdl
blob: 7a12aafda650319424d06683d8a317411fef3d8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
------------------------------------------------
--!  Test intent : declaration of procedure in package
--!  Test scope  : function with active checking
--!  Keywords    : [function, attribute, active]
--!  References  : [VH2000 1.1:]
--!                [Rlink REQ00:2.1.1.2.1]
--!                [Rlink REQ00:14.1.38]
--
-------------------------------------------------
--  declare a procedures and functions to demonstrate
--  attributes.
--    with partially driven bus we should see ativity as expected.
--   
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.subs_pkg.all;

package proc_pkg is

  type ctl_if_t is record
    d1 : std_logic_vector(31 downto 0);
    d2 : std_logic_vector(31 downto 0);
    a1 : std_logic_vector(15 downto 0);
    wr  : std_logic;
    di  : std_logic_vector(63 downto 0);
    dv  : std_logic;
  end record;

  type rsp_if_t is record
    do1 : std_logic_vector(31 downto 0);
    do2 : std_logic_vector(31 downto 0);
    sel : std_logic_vector(3 downto 0);
    addr : std_logic_vector(11 downto 0);
    do  : std_logic_vector(63 downto 0);
  end record;

  type marr_t is array(15 downto 0) of std_logic_vector(63 downto 0);
  type arr_marr_t is array(3 downto 0) of marr_t;

  procedure mem_access(signal ctl : in ctl_if_t;
                       signal rsp : out rsp_if_t;
                       signal mem : inout arr_marr_t;
                       signal ack : out std_logic);

  procedure mem_obj(signal mem : in marr_t;
                    signal addr : in std_logic_vector(11 downto 0);
                    signal wr : in std_logic;
                    signal w_in : in std_logic_vector(63 downto 0);
                    signal mem_out : out marr_t;
                    signal dout : out std_logic_vector(63 downto 0)
                    );

  procedure proc_mix(signal val1 : in std_logic_vector;
                     signal val2 : in std_logic_vector);

  function kslv2int(vec : std_logic_vector) return integer;
  
  function active_bit(signal vec : std_logic_vector;
                      idx : integer) return boolean;

  function active_bits(signal vec : std_logic_vector) return std_logic_vector;

  procedure act_mon(signal ctl : in ctl_if_t;
                    signal rsp : in rsp_if_t;
                    signal act : out boolean
                    );

end package proc_pkg;

package body proc_pkg is

  --  activity  functions.
  function active_bit(signal vec : std_logic_vector;
                      idx : integer) return boolean is
  begin
    return vec(idx)'active;
  end function;
  

  function active_bits(signal vec : std_logic_vector) return std_logic_vector is
    variable rtnv : std_logic_vector(vec'range);
  begin
    for i in vec'range loop
      if active_bit(vec, i) then
        rtnv(i) := '1';
      else
        rtnv(i) := '0';
      end if;
    end loop;
    return rtnv;
  end function;


  -- convert std_logic_vector to integer.
  function kslv2int(vec : std_logic_vector) return integer is
    variable rtn : integer := 0;
    variable len : integer := (vec'length) - 1;
  begin
    --report "Vector in: " & slv2str(vec);
    for i in vec'range loop
      if vec(i) = '1' then
        rtn := rtn + (2**i);
      end if;
    end loop;
    --report "Integer out: " & integer'image(rtn);
    return rtn;
  end function;

  procedure act_mon(signal ctl : in ctl_if_t;
                    signal rsp : in rsp_if_t;
                    signal act : out boolean
                    ) is
  variable delta : integer := 0;
  variable ltime : time;
  begin
    while true loop
      act <= false;
      if ctl'active then
        report "ctl is active ...";
      end if;
      
      if rsp'active then
        report "rsp is active ...";
      end if;
      
      if ctl'active or rsp'active then
        if ltime = now then
          delta := delta + 1;
        else
          delta := 0;
        end if;
        report "delta now at: " & integer'image(delta);
        act <= true;
      end if;
      ltime := now;
      --wait for 0 ps;
      wait on ctl, rsp;
    end loop;
  end procedure;
  


  -- access the memory passed.
  procedure mem_obj(signal mem : in marr_t;
                    signal addr : in std_logic_vector(11 downto 0);
                    signal wr : in std_logic;
                    signal w_in : in std_logic_vector(63 downto 0);
                    signal mem_out : out marr_t;
                    signal dout : out std_logic_vector(63 downto 0)
                    ) is
    variable idx : integer := 0;
  begin
    idx := kslv2int(addr);
    --report integer'image(idx);
    dout(63 downto 16) <= mem(kslv2int(addr(3 downto 0)))(63 downto 16);
    mem_out <= mem;
    if wr = '1' then
      --report "Writing mem ...";
      mem_out(kslv2int(addr(3 downto 0))) <= w_in;
    end if;
    wait for 0 ps;
  end procedure;

  -- do a request for memory access.
  procedure mem_access(signal ctl : in ctl_if_t;
                       signal rsp : out rsp_if_t;
                       signal mem : inout arr_marr_t;
                       signal ack : out std_logic) is
    --variable rsp_v : std_logic;
    variable idx : integer;
  begin
    ack <= '0';
    case ctl.a1(7 downto 4) is
      when "0000" =>
        mem_obj(mem(0), ctl.a1(11 downto 0), ctl.wr, ctl.di, mem(0), rsp.do);
      when "0001" =>
        mem_obj(mem(1), ctl.a1(11 downto 0), ctl.wr, ctl.di, mem(1), rsp.do);
      when "0010" =>
        mem_obj(mem(2), ctl.a1(11 downto 0), ctl.wr, ctl.di, mem(2), rsp.do);
      when "0011" =>
        mem_obj(mem(3), ctl.a1(11 downto 0), ctl.wr, ctl.di, mem(3), rsp.do);
      when others =>
        mem_obj(mem(0), ctl.a1(11 downto 0), ctl.wr, ctl.di, mem(0), rsp.do);
    end case;
  
    ack <= '1';
    --wait until  = '1';
  end procedure;
    
    --  the test procedure implemenation
    procedure proc_mix(signal val1 : in std_logic_vector;
                       signal val2 : in std_logic_vector) is
      variable tmp : bit_vector(val1'high downto val1'low);
      variable tmp2 : bit_vector(val2'high downto val2'low);
    begin
      report "-----  start of call  ----";
      wait for 0.5 ns;   --<<  get us off the rising edge event let data settle
      tmp := to_bitvector(val1);
      report "val1 got: " & bv2str(tmp);
      tmp2 := to_bitvector(val2);
      report "val2 got: " & bv2str(tmp2);
      wait for 2 ns;   --<<  get us off the rising edge after next data change.
      report "-----   then  ----";
      tmp := to_bitvector(val1);
      report "val1 got: " & bv2str(tmp);
      tmp2 := to_bitvector(val2);
      report "val2 got: " & bv2str(tmp2);
    end procedure;
    
end proc_pkg;