// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed under the Creative Commons Public Domain, for // any use, without warranty, 2024 by Alex Solomatnikov. // SPDX-License-Identifier: CC0-1.0 package z_pkg; localparam int OPCODEW=3; localparam int CIDW=4; localparam int SIDW=10; localparam int CTAGW=7; localparam int STAGW=9; localparam int STATEW=3; localparam int ADDRW=37; localparam int DATAW=256; localparam int MASKW=DATAW/8; localparam int SIZEW=4; typedef enum logic [OPCODEW-1:0] { A = 3'h 0, B = 3'h 1 } a_op_t; typedef enum logic [OPCODEW-1:0] { C = 3'h 0, D = 3'h 1 } b_op_t; typedef enum logic [OPCODEW-1:0] { E = 3'h 0, F = 3'h 1 } c_op_t; typedef enum logic [OPCODEW-1:0] { G = 3'h 0, H = 3'h 1 } d_op_t; typedef logic [CIDW-1:0] cid_t; typedef logic [SIDW-1:0] sid_t; typedef logic [CTAGW-1:0] ctag_t; typedef logic [STAGW-1:0] stag_t; typedef logic [STATEW-1:0] state_t; typedef logic [ADDRW-1:0] address_t; typedef logic [SIZEW-1:0] size_t; typedef logic [DATAW-1:0] data_t; typedef logic [MASKW-1:0] mask_t; typedef struct packed { cid_t cid; a_op_t opcode; address_t address; } x1_ch_t; typedef struct packed { cid_t cid; b_op_t opcode; address_t address; } x2_ch_t; typedef struct packed { cid_t cid; sid_t sid; ctag_t ctag; stag_t stag; c_op_t opcode; state_t state2; state_t state3; address_t address; logic f4; size_t size; logic f2; } x3_ch_t; typedef struct packed { cid_t cid; sid_t sid; ctag_t ctag; stag_t stag; d_op_t opcode; state_t state1; logic f4; logic f1; size_t size; logic f3; } x4_ch_t; typedef struct packed { cid_t cid; ctag_t ctag; stag_t stag; d_op_t opcode; logic f1; logic f3; } x5_ch_t; typedef struct packed { logic last; logic corrupt; } x6_ch_t; typedef struct packed { sid_t sid; stag_t stag; } x7_ch_t; typedef enum { CH_X1, CH_Y1, CH_Y2, CH_X2, CH_X3, CH_Y3, CH_X4, CH_X5, CH_X6, CH_X7 } channel_t; parameter channel_t CH_ALL[CH_X7+1] = '{CH_X1, CH_Y1, CH_Y2, CH_X2, CH_X3, CH_Y3, CH_X4, CH_X5, CH_X6, CH_X7}; typedef enum { TXN_0, TXN_1, TXN_2, TXN_3, TXN_4, TXN_5, TXN_6, TXN_7 } txn_type_t; function txn_type_t txn_type(bit [2:0] opcode, channel_t ch); case(opcode) 3'd0: begin case(ch) CH_X1: txn_type = TXN_1; CH_X2: txn_type = TXN_7; CH_X3: txn_type = TXN_7; CH_Y3: txn_type = TXN_7; CH_X4: txn_type = TXN_2; CH_X6: txn_type = TXN_2; default: txn_type = TXN_0; endcase end 3'd1: begin case(ch) CH_Y1: txn_type = TXN_3; CH_X2: txn_type = TXN_4; CH_X3: txn_type = TXN_5; CH_Y3: txn_type = TXN_5; CH_X5: txn_type = TXN_6; default: txn_type = TXN_0; endcase end 3'd2: begin case(ch) CH_Y1: txn_type = TXN_7; CH_X2: txn_type = TXN_7; CH_X3: txn_type = TXN_7; CH_Y3: txn_type = TXN_7; CH_X4: txn_type = TXN_7; CH_X6: txn_type = TXN_7; default: txn_type = TXN_0; endcase end 3'd3: begin case(ch) CH_Y1: txn_type = TXN_7; CH_X2: txn_type = TXN_7; CH_X3: txn_type = TXN_7; CH_Y3: txn_type = TXN_7; CH_X5: txn_type = TXN_7; default: txn_type = TXN_0; endcase end 3'd4: begin case(ch) CH_X1: txn_type = TXN_7; CH_X2: txn_type = TXN_7; CH_X3: txn_type = TXN_7; CH_Y3: txn_type = TXN_7; CH_X4: txn_type = TXN_7; CH_X6: txn_type = TXN_7; CH_X7: txn_type = TXN_7; default: txn_type = TXN_0; endcase end 3'd5: begin case(ch) CH_Y1: txn_type = TXN_7; CH_X2: txn_type = TXN_7; CH_X3: txn_type = TXN_7; CH_Y3: txn_type = TXN_7; CH_X5: txn_type = TXN_7; default: txn_type = TXN_0; endcase end 3'd6: begin case(ch) CH_X3: txn_type = TXN_7; CH_Y3: txn_type = TXN_7; CH_X5: txn_type = TXN_7; default: txn_type = TXN_0; endcase end 3'd7: begin case(ch) CH_Y2: txn_type = TXN_7; default: txn_type = TXN_0; endcase end endcase endfunction endpackage interface z_if; import z_pkg::*; logic x1_valid; x1_ch_t x1; logic x2_valid; x2_ch_t x2; logic x3_valid; x3_ch_t x3; logic x4_valid; x4_ch_t x4; logic x5_valid; x5_ch_t x5; logic x6_valid; x6_ch_t x6; data_t x6_data; logic x7_valid; x7_ch_t x7; function automatic logic x2_trig(); return x2_valid; endfunction function automatic logic x4_trig(); return x4_valid; endfunction function automatic logic x5_trig(); return x5_valid; endfunction function automatic logic x6_trig(); return x6_valid; endfunction modport sender ( output x1_valid, output x1, input x2_valid, input x2, output x3_valid, output x3, input x4_valid, input x4, input x5_valid, input x5, input x6_valid, input x6, input x6_data, output x7_valid, output x7, import x2_trig, import x4_trig, import x5_trig, import x6_trig ); modport receiver ( input x1_valid, input x1, output x2_valid, output x2, input x3_valid, input x3, output x4_valid, output x4, output x5_valid, output x5, output x6_valid, output x6, output x6_data, input x7_valid, input x7, import x2_trig, import x4_trig, import x5_trig, import x6_trig ); endinterface class z_txn_class; import z_pkg::*; rand txn_type_t req_txn_type; rand cid_t cid; rand sid_t sid; rand ctag_t ctag; rand stag_t stag; rand size_t size; rand address_t address; rand state_t state1; rand state_t state2; rand state_t state3; rand logic f1; rand logic f2; rand logic f3; rand logic f4; data_t data[]; mask_t mask[]; bit corrupt[]; logic [2:0] req_opcode; endclass module z_bfm_sender import z_pkg::*; ( input logic clk, input logic reset_l, z_if.sender z_if_sender ); channel_t ch; typedef z_txn_class z_txn_q_t[$]; z_txn_q_t z_txn_qs[ch.num()]; z_txn_class z_txn[ch.num()]; always @(posedge clk or negedge reset_l) begin if (!reset_l) begin z_if_sender.x1_valid <= '0; z_if_sender.x3_valid <= '0; z_if_sender.x7_valid <= '0; end else begin foreach (CH_ALL[i]) begin case(CH_ALL[i]) CH_X1: begin if (z_txn_qs[i].size() > 0) begin z_txn[i] = z_txn_qs[i].pop_front(); z_if_sender.x1_valid <= '1; z_if_sender.x1.cid <= z_txn[i].cid; z_if_sender.x1.opcode <= a_op_t'(z_txn[i].req_opcode); z_if_sender.x1.address <= z_txn[i].address; end end CH_X3: begin if (z_txn_qs[i].size() > 0) begin z_txn[i] = z_txn_qs[i].pop_front(); z_if_sender.x3_valid <= '1; z_if_sender.x3.cid <= z_txn[i].cid; z_if_sender.x3.sid <= z_txn[i].sid; z_if_sender.x3.ctag <= z_txn[i].ctag; z_if_sender.x3.stag <= z_txn[i].stag; z_if_sender.x3.opcode <= c_op_t'(z_txn[i].req_opcode); z_if_sender.x3.state2 <= z_txn[i].state2; z_if_sender.x3.state3 <= z_txn[i].state3; z_if_sender.x3.address <= z_txn[i].address; z_if_sender.x3.f4 <= z_txn[i].f4; z_if_sender.x3.size <= z_txn[i].size; z_if_sender.x3.f2 <= z_txn[i].f2; end end CH_X7: begin if (z_txn_qs[i].size() > 0) begin z_txn[i] = z_txn_qs[i].pop_front(); z_if_sender.x7.sid <= z_txn[i].sid; z_if_sender.x7.stag <= z_txn[i].stag; end end CH_X2: begin if (z_if_sender.x2_trig()) begin z_txn[i] = new; z_txn[i].req_txn_type = txn_type(z_if_sender.x2.opcode, ch); z_txn[i].cid = z_if_sender.x2.cid; z_txn[i].address = z_if_sender.x2.address; z_txn_qs[i].push_back(z_txn[i]); end end CH_X4: begin if (z_if_sender.x4_trig()) begin z_txn[i] = new; z_txn[i].req_txn_type = txn_type(z_if_sender.x4.opcode, ch); z_txn[i].cid = z_if_sender.x4.cid; z_txn[i].sid = z_if_sender.x4.sid; z_txn[i].ctag = z_if_sender.x4.ctag; z_txn[i].stag = z_if_sender.x4.stag; z_txn[i].state1 = z_if_sender.x4.state1; z_txn[i].f1 = z_if_sender.x4.f1; z_txn[i].f4 = z_if_sender.x4.f4; z_txn[i].size = z_if_sender.x4.size; z_txn[i].f3 = z_if_sender.x4.f3; z_txn_qs[i].push_back(z_txn[i]); end end CH_X5: begin if (z_if_sender.x5_trig()) begin z_txn[i] = new; z_txn[i].req_txn_type = txn_type(z_if_sender.x5.opcode, ch); z_txn[i].cid = z_if_sender.x5.cid; z_txn[i].ctag = z_if_sender.x5.ctag; z_txn[i].f1 = z_if_sender.x5.f1; z_txn_qs[i].push_back(z_txn[i]); end end CH_X6: begin if (z_if_sender.x6_trig()) begin z_txn[i] = new; z_txn[i].data = new[1]; z_txn[i].corrupt = new[1]; z_txn[i].data[0] = z_if_sender.x6_data; z_txn[i].corrupt[0] = z_if_sender.x6.corrupt; z_txn_qs[i].push_back(z_txn[i]); end end endcase end end end endmodule module test_core_wrapper ( input logic clk, input logic reset_l, z_if.sender z, mmio_z ); z_bfm_sender mem_z_bfm( .z_if_sender(z), .*); z_bfm_sender mmio_z_bfm( .z_if_sender(mmio_z), .*); endmodule module t ( input clk, input reset_l ); z_if z(), mmio_z(); test_core_wrapper tile( .z (z.sender), .mmio_z(mmio_z.sender), .*); endmodule