File: t_interface.v

package info (click to toggle)
verilator 5.038-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 162,552 kB
  • sloc: cpp: 139,204; python: 20,931; ansic: 10,222; yacc: 6,000; lex: 1,925; makefile: 1,260; sh: 494; perl: 282; fortran: 22
file content (170 lines) | stat: -rw-r--r-- 3,235 bytes parent folder | download | duplicates (4)
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
// DESCRIPTION: Verilator: SystemVerilog interface test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Iztok Jeras.
// SPDX-License-Identifier: CC0-1.0

module t (/*AUTOARG*/
   // Inputs
   clk
   );

   input clk;

   logic   rst = 1'b1;  // reset
   integer rst_cnt = 0;

   // reset is removed after a delay
   always @ (posedge clk)
   begin
      rst_cnt <= rst_cnt + 1;
      rst     <= rst_cnt <= 3;
   end

   // counters
   int cnt;
   int cnt_src;
   int cnt_drn;

   // add all counters
   assign cnt = cnt_src + cnt_drn + inf.cnt;

   // finish report
   always @ (posedge clk)
   if (cnt == 3*16) begin
      $write("*-* All Finished *-*\n");
      $finish;
   end

   // interface instance
   handshake inf (
      .clk (clk),
      .rst (rst)
   );

   // source instance
   source #(
      .RW  (8),
      .RP  (8'b11100001)
   ) source (
      .clk  (clk),
      .rst  (rst),
      .inf  (inf),
      .cnt  (cnt_src)
   );

   // drain instance
   drain #(
      .RW  (8),
      .RP  (8'b11010100)
   ) drain (
      .clk  (clk),
      .rst  (rst),
      .inf  (inf),
      .cnt  (cnt_drn)
   );

endmodule : t


// interface definition
interface handshake #(
   parameter int unsigned WC = 32
)(
   input logic clk,
   input logic rst
);

   // modport signals
   logic req;  // request
   logic grt;  // grant
   logic inc;  // increment

   // local signals
   integer cnt;  // counter

   // source
   modport src (
      output req,
      input  grt
   );

   // drain
   modport drn (
      input  req,
      output grt
   );

   // incremet condition
   assign inc = req & grt;

   // local logic (counter)
   always @ (posedge clk, posedge rst)
   if (rst) cnt <= '0;
   else     cnt <= cnt + {31'h0, inc};

endinterface : handshake


// source module
module source #(
   // random generator parameters
   parameter int unsigned RW=1,   // LFSR width
   parameter bit [RW-1:0] RP='0,  // LFSR polinom
   parameter bit [RW-1:0] RR='1   // LFSR reset state
)(
   input logic    clk,
   input logic    rst,
   handshake.src  inf,
   output integer cnt
);

   // LFSR
   logic [RW-1:0] rnd;

   // LFSR in Galois form
   always @ (posedge clk, posedge rst)
   if (rst) rnd <= RR;
   else     rnd <= {rnd[0], rnd[RW-1:1]} ^ ({RW{rnd[0]}} & RP);

   // counter
   always @ (posedge clk, posedge rst)
   if (rst) cnt <= 32'd0;
   else     cnt <= cnt + {31'd0, (inf.req & inf.grt)};

   // request signal
   assign inf.req = rnd[0];

endmodule : source


// drain module
module drain #(
   // random generator parameters
   parameter int unsigned RW=1,   // LFSR width
   parameter bit [RW-1:0] RP='0,  // LFSR polinom
   parameter bit [RW-1:0] RR='1   // LFSR reset state
)(
   input logic    clk,
   input logic    rst,
   handshake.drn  inf,
   output integer cnt
);

   // LFSR
   logic [RW-1:0] rnd;

   // LFSR in Galois form
   always @ (posedge clk, posedge rst)
   if (rst) rnd <= RR;
   else     rnd <= {rnd[0], rnd[RW-1:1]} ^ ({RW{rnd[0]}} & RP);

   // counter
   always @ (posedge clk, posedge rst)
   if (rst) cnt <= 32'd0;
   else     cnt <= cnt + {31'd0, (inf.req & inf.grt)};

   // grant signal
   assign inf.grt = rnd[0];

endmodule : drain