// Copyright 2020 ETH Zurich and University of Bologna. // Solderpad Hardware License, Version 0.51, see LICENSE for details. // SPDX-License-Identifier: SHL-0.51 // Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch> `include "reqrsp_interface/assign.svh" /// Testbench for all idempotent modules i.e., module which do not alter data /// but only the handshaking. module reqrsp_idempotent_tb import reqrsp_pkg::*; #( parameter int unsigned AW = 32, parameter int unsigned DW = 32, parameter int unsigned NrRandomTransactions = 1000, /// Test Isochronous spill register. parameter bit Iso = 1, /// Test normal spill register. parameter bit Cut = 0 ); localparam time ClkPeriod = 10ns; localparam time ApplTime = 2ns; localparam time TestTime = 8ns; logic clk, rst_n; REQRSP_BUS #( .ADDR_WIDTH ( AW ), .DATA_WIDTH ( DW ) ) master (); REQRSP_BUS_DV #( .ADDR_WIDTH ( AW ), .DATA_WIDTH ( DW ) ) master_dv (clk); REQRSP_BUS #( .ADDR_WIDTH ( AW ), .DATA_WIDTH ( DW ) ) slave (); REQRSP_BUS_DV #( .ADDR_WIDTH ( AW ), .DATA_WIDTH ( DW ) ) slave_dv (clk); // Isochronous crossing. if (Iso) begin : gen_iso_dut // We only want to test that the module is properly wired up so we can put it // in bypass which makes this testbench significantly easier as we do not need // to generate a isochronous clock. The iso feature is tested in a separate // testbench in the common_cells repository. reqrsp_iso_intf #( .AddrWidth (AW), .DataWidth (DW), .BypassReq (1), .BypassRsp (1) ) i_dut ( .src_clk_i (clk), .src_rst_ni (rst_n), .src (master), .dst_clk_i (clk), .dst_rst_ni (rst_n), .dst (slave) ); // Plain synchronous cuts. end else if (Cut) begin : gen_cut_dut reqrsp_cut_intf #( .AddrWidth (AW), .DataWidth (DW), .BypassReq (0), .BypassRsp (0) ) i_dut ( .clk_i (clk), .rst_ni (rst_n), .slv (master), .mst (slave) ); end `REQRSP_ASSIGN(master, master_dv) `REQRSP_ASSIGN(slave_dv, slave) // ---------------- // Clock generation // ---------------- initial begin rst_n = 0; repeat (3) begin #(ClkPeriod/2) clk = 0; #(ClkPeriod/2) clk = 1; end rst_n = 1; forever begin #(ClkPeriod/2) clk = 0; #(ClkPeriod/2) clk = 1; end end // ------- // Monitor // ------- typedef reqrsp_test::reqrsp_monitor #( // Reqrsp bus interface paramaters; .AW ( AW ), .DW ( DW ), // Stimuli application and test time .TA ( ApplTime ), .TT ( TestTime ) ) reqrsp_monitor_t; reqrsp_monitor_t reqrsp_mst_monitor = new (master_dv); // Reqrsp Monitor. initial begin @(posedge rst_n); reqrsp_mst_monitor.monitor(); end reqrsp_monitor_t reqrsp_slv_monitor = new (slave_dv); // Reqrsp Monitor. initial begin @(posedge rst_n); reqrsp_slv_monitor.monitor(); end // ------ // Driver // ------ typedef reqrsp_test::rand_reqrsp_slave #( // Reqrsp bus interface paramaters; .AW ( AW ), .DW ( DW ), // Stimuli application and test time .TA ( ApplTime ), .TT ( TestTime ) ) reqrsp_rand_slave_t; reqrsp_rand_slave_t rand_reqrsp_slave = new (slave_dv); initial begin rand_reqrsp_slave.reset(); @(posedge rst_n); rand_reqrsp_slave.run(); end typedef reqrsp_test::rand_reqrsp_master #( // Reqrsp bus interface paramaters; .AW ( AW ), .DW ( DW ), // Stimuli application and test time .TA ( ApplTime ), .TT ( TestTime ) ) reqrsp_rand_master_t; reqrsp_rand_master_t rand_reqrsp_master = new (master_dv); // Reqrsp master. initial begin rand_reqrsp_master.reset(); @(posedge rst_n); rand_reqrsp_master.run(NrRandomTransactions); // Wait until all transactions have ceased. repeat(1000) @(posedge clk); $finish; end // ---------- // Scoreboard // ---------- initial begin forever begin automatic reqrsp_test::req_t req; automatic reqrsp_test::req_t req_slv; automatic reqrsp_test::rsp_t rsp; automatic reqrsp_test::rsp_t rsp_slv; reqrsp_mst_monitor.req_mbx.get(req); reqrsp_mst_monitor.rsp_mbx.get(rsp); reqrsp_slv_monitor.req_mbx.get(req_slv); reqrsp_slv_monitor.rsp_mbx.get(rsp_slv); assert(req_slv.do_compare(req)); assert(rsp_slv.do_compare(rsp)); end end // Check that we have associated all transactions. final begin assert(reqrsp_mst_monitor.req_mbx.num() == 0); assert(reqrsp_mst_monitor.rsp_mbx.num() == 0); assert(reqrsp_slv_monitor.req_mbx.num() == 0); assert(reqrsp_slv_monitor.rsp_mbx.num() == 0); $display("Checked for non-empty mailboxes."); end endmodule