File: t_sv_bus_mux_demux.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 (194 lines) | stat: -rw-r--r-- 7,458 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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// This file is placed into the Public Domain, for any use, without warranty. //
// 2012 by Iztok Jeras                                                        //
// SPDX-License-Identifier: CC0-1.0                                         //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// This testbench contains a bus source and a bus drain. The source creates   //
// address and data bus values, while the drain is the final destination of   //
// such pairs. All source and drain transfers are logged into memories, which //
// are used at the end of simulation to check for data transfer correctness.  //
// Inside the RLT wrapper there is a multiplexer and a demultiplexer, they    //
// bus transfers into a 8bit data stream and back. Both stream input and      //
// output are exposed, they are connected together into a loopback.           //
//                                                                            //
//                    -----------  ---------------------                      //
//                    | bso_mem |  |        wrap       |                      //
//                    -----------  |                   |                      //
//       -----------       |       |    -----------    |                      //
//       | bsi src | ------------> | -> |   mux   | -> | -> -   sto           //
//       -----------               |    -----------    |     \                //
//                                 |                   |      | loopback      //
//       -----------               |    -----------    |     /                //
//       | bso drn | <------------ | <- |  demux  | <- | <- -   sti           //
//       -----------       |       |    -----------    |                      //
//                    -----------  |                   |                      //
//                    | bso_mem |  |                   |                      //
//                    -----------  ---------------------                      //
//                                                                            //
// PROTOCOL:                                                                  //
//                                                                            //
// The 'vld' signal is driven by the source to indicate valid data is         //
// available, 'rdy' is used by the drain to indicate is is ready to accept    //
// valid data. A data transfer only happens if both 'vld' & 'rdy' are active. //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

// include RTL files
`include "t_sv_bus_mux_demux/sv_bus_mux_demux_def.sv"
`include "t_sv_bus_mux_demux/sv_bus_mux_demux_demux.sv"
`include "t_sv_bus_mux_demux/sv_bus_mux_demux_mux.sv"
`include "t_sv_bus_mux_demux/sv_bus_mux_demux_wrap.sv"

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

input clk;

parameter SIZ = 10;

// system signals
//logic        clk = 1'b1;  // clock
logic        rst = 1'b1;  // reset
integer      rst_cnt = 0;

// input bus
logic        bsi_vld;  // valid (chip select)
logic [31:0] bsi_adr;  // address
logic [31:0] bsi_dat;  // data
logic        bsi_rdy;  // ready (acknowledge)
logic        bsi_trn;  // data transfer
logic [31:0] bsi_mem [SIZ];
// output stream
logic        sto_vld;  // valid (chip select)
logic  [7:0] sto_bus;  // data bus
logic        sto_rdy;  // ready (acknowledge)

// input stream
logic        sti_vld;  // valid (chip select)
logic  [7:0] sti_bus;  // data bus
logic        sti_rdy;  // ready (acknowledge)
// output bus
logic        bso_vld;  // valid (chip select)
logic [31:0] bso_adr;  // address
logic [31:0] bso_dat;  // data
logic        bso_rdy;  // ready (acknowledge)
logic        bso_trn;  // data transfer
logic [31:0] bso_mem [SIZ];
integer      bso_cnt = 0;

////////////////////////////////////////////////////////////////////////////////
// clock and reset
////////////////////////////////////////////////////////////////////////////////

// clock toggling
//always #5  clk = ~clk;

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

// reset is removed after a delay
always @ (posedge clk)
if (bso_cnt == SIZ) begin
  if (bsi_mem === bso_mem)  begin  $write("*-* All Finished *-*\n"); $finish();  end
  else                      begin  $display ("FAILED"); $stop();  end
end

////////////////////////////////////////////////////////////////////////////////
// input data generator
////////////////////////////////////////////////////////////////////////////////

// input data transfer
assign bsi_trn = bsi_vld & bsi_rdy;

// valid (for SIZ transfers)
always @ (posedge clk, posedge rst)
if (rst)          bsi_vld = 1'b0;
else              bsi_vld = (bsi_adr < SIZ);

// address (increments every transfer)
always @ (posedge clk, posedge rst)
if (rst)          bsi_adr <= 32'h00000000;
else if (bsi_trn) bsi_adr <= bsi_adr + 'd1;

// data (new random value generated after every transfer)
always @ (posedge clk, posedge rst)
if (rst)          bsi_dat <= 32'h00000000;
else if (bsi_trn) bsi_dat <= $random();

// storing transferred data into memory for final check
always @ (posedge clk)
if (bsi_trn) bsi_mem [bsi_adr] <= bsi_dat;

////////////////////////////////////////////////////////////////////////////////
// RTL instance
////////////////////////////////////////////////////////////////////////////////

sv_bus_mux_demux_wrap wrap (
  // system signals
  .clk      (clk),
  .rst      (rst),
  // input bus
  .bsi_vld  (bsi_vld),
  .bsi_adr  (bsi_adr),
  .bsi_dat  (bsi_dat),
  .bsi_rdy  (bsi_rdy),
  // output stream
  .sto_vld  (sto_vld),
  .sto_bus  (sto_bus),
  .sto_rdy  (sto_rdy),
  // input stream
  .sti_vld  (sti_vld),
  .sti_bus  (sti_bus),
  .sti_rdy  (sti_rdy),
  // output bus
  .bso_vld  (bso_vld),
  .bso_adr  (bso_adr),
  .bso_dat  (bso_dat),
  .bso_rdy  (bso_rdy)
);

// stream output from mux is looped back into stream input for demux
assign sti_vld = sto_vld;
assign sti_bus = sto_bus;
assign sto_rdy = sti_rdy;

////////////////////////////////////////////////////////////////////////////////
// output data monitor
////////////////////////////////////////////////////////////////////////////////

// input data transfer
assign bso_trn = bso_vld & bso_rdy;

// output transfer counter used to end the test
always @ (posedge clk, posedge rst)
if (rst)           bso_cnt <= 0;
else if (bso_trn)  bso_cnt <= bso_cnt + 1;

// storing transferred data into memory for final check
always @ (posedge clk)
if (bso_trn)  bso_mem [bso_adr] <= bso_dat;

// every output transfer against expected value stored in memory
always @ (posedge clk)
if (bso_trn && (bsi_mem [bso_adr] !== bso_dat))
$display ("@%08h i:%08h o:%08h", bso_adr, bsi_mem [bso_adr], bso_dat);

// ready is active for SIZ transfers
always @ (posedge clk, posedge rst)
if (rst)  bso_rdy = 1'b0;
else      bso_rdy = 1'b1;

endmodule