Verilator

Форк
0
/
verilated_std.sv 
192 строки · 4.8 Кб
1
// DESCRIPTION: Verilator: built-in packages and classes
2
//
3
// Code available from: https://verilator.org
4
//
5
//*************************************************************************
6
//
7
// Copyright 2022-2024 by Wilson Snyder. This program is free software; you can
8
// redistribute it and/or modify it under the terms of either the GNU Lesser
9
// General Public License Version 3 or the Perl Artistic License Version 2.0.
10
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
11
//
12
//*************************************************************************
13
///
14
/// \file
15
/// \brief Verilated IEEE std:: header
16
///
17
/// This file is included automatically by Verilator when a std::mailbox or
18
/// std::semaphore is referenced.
19
///
20
/// This file is not part of the Verilated public-facing API.
21
/// It is only for internal use.
22
///
23
//*************************************************************************
24

25
// verilator lint_off DECLFILENAME
26
// verilator lint_off TIMESCALEMOD
27
// verilator lint_off UNUSEDSIGNAL
28
package std;
29
   class mailbox #(type T);
30
      protected int m_bound;
31
      protected T m_queue[$];
32

33
      function new(int bound = 0);
34
         m_bound = bound;
35
      endfunction
36

37
      function int num();
38
         return m_queue.size();
39
      endfunction
40

41
      task put(T message);
42
`ifdef VERILATOR_TIMING
43
         if (m_bound != 0)
44
            wait (m_queue.size() < m_bound);
45
         m_queue.push_back(message);
46
`endif
47
      endtask
48

49
      function int try_put(T message);
50
         if (m_bound == 0 || num() < m_bound) begin
51
            m_queue.push_back(message);
52
            return 1;
53
         end
54
         return 0;
55
      endfunction
56

57
      task get(ref T message);
58
`ifdef VERILATOR_TIMING
59
         wait (m_queue.size() > 0);
60
         message = m_queue.pop_front();
61
`endif
62
      endtask
63

64
      function int try_get(ref T message);
65
         if (num() > 0) begin
66
            message = m_queue.pop_front();
67
            return 1;
68
         end
69
         return 0;
70
      endfunction
71

72
      task peek(ref T message);
73
`ifdef VERILATOR_TIMING
74
         wait (m_queue.size() > 0);
75
         message = m_queue[0];
76
`endif
77
      endtask
78

79
      function int try_peek(ref T message);
80
         if (num() > 0) begin
81
            message = m_queue[0];
82
            return 1;
83
         end
84
         return 0;
85
      endfunction
86
   endclass
87

88
   class semaphore;
89
      protected int m_keyCount;
90

91
      function new(int keyCount = 0);
92
         m_keyCount = keyCount;
93
      endfunction
94

95
      function void put(int keyCount = 1);
96
         m_keyCount += keyCount;
97
      endfunction
98

99
      task get(int keyCount = 1);
100
`ifdef VERILATOR_TIMING
101
         wait (m_keyCount >= keyCount);
102
         m_keyCount -= keyCount;
103
`endif
104
      endtask
105

106
      function int try_get(int keyCount = 1);
107
         if (m_keyCount >= keyCount) begin
108
            m_keyCount -= keyCount;
109
            return 1;
110
         end
111
         return 0;
112
      endfunction
113
   endclass
114

115
   class process;
116
      typedef enum {
117
         FINISHED  = 0,
118
         RUNNING   = 1,
119
         WAITING   = 2,
120
         SUSPENDED = 3,
121
         KILLED    = 4
122
      } state;
123

124
`ifdef VERILATOR_TIMING
125
      // Width visitor changes it to VlProcessRef
126
      protected chandle m_process;
127
`endif
128

129
      static function process self();
130
         process p = new;
131
`ifdef VERILATOR_TIMING
132
         $c(p.m_process, " = vlProcess;");
133
`endif
134
         return p;
135
      endfunction
136

137
      protected function void set_status(state s);
138
`ifdef VERILATOR_TIMING
139
         $c(m_process, "->state(", s, ");");
140
`endif
141
      endfunction
142

143
      function state status();
144
`ifdef VERILATOR_TIMING
145
         return state'($c(m_process, "->state()"));
146
`else
147
         return RUNNING;
148
`endif
149
      endfunction
150

151
      function void kill();
152
         set_status(KILLED);
153
      endfunction
154

155
      function void suspend();
156
         $error("std::process::suspend() not supported");
157
      endfunction
158

159
      function void resume();
160
         set_status(RUNNING);
161
      endfunction
162

163
      task await();
164
`ifdef VERILATOR_TIMING
165
         wait (status() == FINISHED || status() == KILLED);
166
`endif
167
      endtask
168

169
      // When really implemented, srandom must operate on the process, but for
170
      // now rely on the srandom() that is automatically generated for all
171
      // classes.
172
      //
173
      // function void srandom(int seed);
174
      // endfunction
175

176
      // The methods below work only if set_randstate is never applied to
177
      // a state string created before another such string. Full support
178
      // could use VlRNG class to store the state per process in VlProcess
179
      // objects.
180
      function string get_randstate();
181
         string s;
182

183
         s.itoa($random);  // Get a random number
184
         set_randstate(s);  // Pretend it's the state of RNG
185
         return s;
186
      endfunction
187

188
      function void set_randstate(string s);
189
         $urandom(s.atoi());  // Set the seed using a string
190
      endfunction
191
   endclass
192
endpackage
193

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.