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
|