1//
2// Copyright 2016 Ettus Research
3//
4
5module axi_fifo_2clk_tb();
6
7    localparam WIDTH    = 32;
8    localparam SIZE     = 5;
9
10    reg                 s_axis_clk;
11    reg                 s_axis_rst;
12    reg [WIDTH-1:0]     s_axis_tdata;
13    reg                 s_axis_tvalid;
14    reg                 s_axis_tlast;
15    wire                s_axis_tready;
16    reg                 m_axis_clk;
17    reg                 m_axis_rst;
18    wire [WIDTH-1:0]    m_axis_tdata;
19    wire                m_axis_tvalid;
20    wire                m_axis_tlast;
21    reg                 m_axis_tready;
22    wire [SIZE:0]       s_axis_occupied;
23    wire                s_axis_full;
24    wire                s_axis_empty;
25    wire [SIZE:0]       m_axis_occupied;
26    wire                m_axis_full;
27    wire                m_axis_empty;
28
29    axi_fifo_2clk #(.SIZE(SIZE),.WIDTH(WIDTH)) axi_fifo_2clk (
30        .s_axis_clk(s_axis_clk),
31        .s_axis_rst(s_axis_rst),
32        .s_axis_tdata(s_axis_tdata),
33        .s_axis_tvalid(s_axis_tvalid),
34        .s_axis_tlast(s_axis_tlast),
35        .s_axis_tready(s_axis_tready),
36        .m_axis_clk(m_axis_clk),
37        .m_axis_rst(m_axis_rst),
38        .m_axis_tdata(m_axis_tdata),
39        .m_axis_tvalid(m_axis_tvalid),
40        .m_axis_tlast(m_axis_tlast),
41        .m_axis_tready(m_axis_tready),
42        .s_axis_occupied(s_axis_occupied),
43        .s_axis_full(s_axis_full),
44        .s_axis_empty(s_axis_empty),
45        .m_axis_occupied(m_axis_occupied),
46        .m_axis_full(m_axis_full),
47        .m_axis_empty(m_axis_empty));
48
49    `define S_AXIS_CLK_PERIOD 7
50    initial begin
51        s_axis_clk = 1'b0;
52        forever begin
53            #(`S_AXIS_CLK_PERIOD/2) s_axis_clk = ~s_axis_clk;
54        end
55    end
56
57    `define S_AXIS_RESET_PERIOD 70
58    initial begin
59        s_axis_rst = 1'b1;
60        #(`S_AXIS_RESET_PERIOD) s_axis_rst = 1'b0;
61    end
62
63    `define M_AXIS_CLK_PERIOD 10
64    initial begin
65        m_axis_clk = 1'b0;
66        forever begin
67            #(`M_AXIS_CLK_PERIOD/2) m_axis_clk = ~m_axis_clk;
68        end
69    end
70
71    `define M_AXIS_RESET_PERIOD 100
72    initial begin
73        m_axis_rst = 1'b1;
74        #(`M_AXIS_RESET_PERIOD) m_axis_rst = 1'b0;
75    end
76
77    initial begin
78        @(posedge m_axis_clk);
79        @(posedge s_axis_clk);
80        s_axis_tdata  = 'd0;
81        s_axis_tlast  = 1'b0;
82        s_axis_tvalid = 1'b0;
83        m_axis_tready = 1'b0;
84        assert(~s_axis_full && ~m_axis_full)                 else $error("FIFO is full during reset!");
85        assert(s_axis_empty == 1'b1 && m_axis_empty == 1'b1) else $error("FIFO is not empty during reset!");
86        assert(s_axis_occupied == 0 && m_axis_occupied == 0) else $error("FIFO is occupied during reset!");
87        while (s_axis_rst) @(negedge s_axis_rst);
88        while (m_axis_rst) @(negedge m_axis_rst);
89        @(posedge m_axis_clk);
90        @(posedge s_axis_clk);
91        assert(~s_axis_full && ~m_axis_full)                 else $error("FIFO is full after reset!");
92        assert(s_axis_empty == 1'b1 && m_axis_empty == 1'b1) else $error("FIFO is not empty after reset!");
93        assert(s_axis_occupied == 0 && m_axis_occupied == 0) else $error("FIFO is occupied after reset!");
94        // Fill FIFO
95        while (~s_axis_tready) @(posedge s_axis_clk);
96        for (int i = 0; i < 1 << DEPTH_LOG2; i++) begin
97            s_axis_tdata  = i+1'b1;
98            s_axis_tvalid = 1'b1;
99            @(posedge s_axis_clk);
100        end
101        repeat (6) @(posedge s_axis_clk);
102        assert(s_axis_full && m_axis_full) else $error("Incorrect FIFO full flag!");
103        assert(~s_axis_empty && ~m_axis_empty) else $error("Incorrect FIFO empty flag!");
104        assert(s_axis_occupied == (1 << DEPTH_LOG2) && m_axis_occupied == (1 << DEPTH_LOG2)) else $error("Incorrect FIFO occupied count!");
105        // Empty FIFO
106        s_axis_tdata  = 'd0;
107        s_axis_tvalid = 1'b0;
108        @(posedge m_axis_clk);
109        while (~m_axis_tvalid) @(posedge m_axis_clk);
110        for (int i = 0; i < 1 << DEPTH_LOG2; i++) begin
111            m_axis_tready = 1'b1;
112            @(posedge m_axis_clk);
113            assert(m_axis_tdata == i+1'b1) else $error("Incorrect FIFO data! (read)");
114        end
115        repeat (6) @(posedge m_axis_clk);
116        assert(~s_axis_full && ~m_axis_full) else $error("Incorrect FIFO full flag!");
117        assert(s_axis_empty && m_axis_empty) else $error("Incorrect FIFO empty flag!");
118        assert(s_axis_occupied == 0 && m_axis_occupied == 0) else $error("Incorrect FIFO occupied count!");
119    end
120
121endmodule