OpenCores
URL https://opencores.org/ocsvn/sd_card_controller/sd_card_controller/trunk

Subversion Repositories sd_card_controller

[/] [sd_card_controller/] [trunk/] [bench/] [verilog/] [sd_data_master_tb.sv] - Rev 8

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// WISHBONE SD Card Controller IP Core                          ////
////                                                              ////
//// sd_data_master_tb.sv                                         ////
////                                                              ////
//// This file is part of the WISHBONE SD Card                    ////
//// Controller IP Core project                                   ////
//// http://opencores.org/project,sd_card_controller              ////
////                                                              ////
//// Description                                                  ////
//// testbench for sd_data_master module                          ////
////                                                              ////
//// Author(s):                                                   ////
////     - Marek Czerski, ma.czerski@gmail.com                    ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2013 Authors                                   ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE. See the GNU Lesser General Public License for more  ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////

`include "sd_defines.h"

module sd_data_master_tb();

parameter SD_TCLK = 20; // 50 MHz -> timescale 1ns

reg sd_clk;
reg rst;
reg start_tx_i;
reg start_rx_i;
wire d_write_o;
wire d_read_o;
wire start_tx_fifo_o;
wire start_rx_fifo_o;
reg tx_fifo_empty_i;
reg tx_fifo_full_i;
reg rx_fifo_full_i;
reg xfr_complete_i;
reg crc_ok_i;
//2 - fifo un/ov
//1 - wrong crc
//0 - completed
wire [`INT_DATA_SIZE-1:0] int_status_o;
reg int_status_rst_i;

task test_read;
    input crc_ok;
    begin
        start_tx_i = 1; //start filling tx fifo
        #SD_TCLK;
        start_tx_i = 0;
        wait(start_tx_fifo_o == 1);
        #(SD_TCLK/2);
        assert(d_write_o == 0);
        assert(d_read_o == 0);
        assert(start_rx_fifo_o == 0);
        #(4*SD_TCLK);
        tx_fifo_full_i = 1; //tx fifo is full
        wait(d_write_o == 1);
        #(SD_TCLK/2);
        xfr_complete_i = 0; //serial_data_host starts its state machine
        assert(d_read_o == 0);
        assert(start_tx_fifo_o == 1);
        assert(start_rx_fifo_o == 0);
        #(2*SD_TCLK);
        //check if d_write_o went low
        assert(d_write_o == 0);
        #(10*SD_TCLK);
        tx_fifo_full_i = 0;
        xfr_complete_i = 1;
        crc_ok_i = crc_ok;
        #SD_TCLK;
        //xfr_complete_i = 0; //signl stays in logic 1 after transmission
        crc_ok_i = 0;
        assert(d_write_o == 0);
        assert(d_read_o == 0);    
        wait(start_tx_fifo_o == 0);
        #(SD_TCLK/2);
        assert(start_rx_fifo_o == 0);
        if (crc_ok)
            assert(int_status_o == 1);
        else
            assert(int_status_o == 2);
        
        //reset int status
        int_status_rst_i = 1;
        #SD_TCLK;
        int_status_rst_i = 0;
        assert(int_status_o == 0);
    end
endtask

task test_write;
    input crc_ok;
    begin
        start_rx_i = 1; //start filling rx fifo and start sd_data_serial_host
        #SD_TCLK;
        start_rx_i = 0;
        wait(start_rx_fifo_o == 1 && d_read_o == 1);
        #(SD_TCLK/2);
        xfr_complete_i = 0; //serial_data_host starts its state machine
        assert(d_write_o == 0);
        assert(start_tx_fifo_o == 0);
        #(2*SD_TCLK);
        //check if d_read_o went low
        assert(d_read_o == 0);
        #(10*SD_TCLK);
        xfr_complete_i = 1;
        crc_ok_i = crc_ok;
        #SD_TCLK;
        //xfr_complete_i = 0; //signl stays in logic 1 after transmission
        crc_ok_i = 0;
        assert(d_write_o == 0);
        assert(d_read_o == 0);
        wait(start_rx_fifo_o == 0);
        #(SD_TCLK/2);
        assert(start_rx_fifo_o == 0);
        if (crc_ok)
            assert(int_status_o == 1);
        else
            assert(int_status_o == 2);
        
        //reset int status
        int_status_rst_i = 1;
        #SD_TCLK;
        int_status_rst_i = 0;
        assert(int_status_o == 0);
    end
endtask

sd_data_master sd_data_master_dut(
           .sd_clk(sd_clk),
           .rst(rst),
           .start_tx_i(start_tx_i),
           .start_rx_i(start_rx_i),
           .d_write_o(d_write_o),
           .d_read_o(d_read_o),
           .start_tx_fifo_o(start_tx_fifo_o),
           .start_rx_fifo_o(start_rx_fifo_o),
           .tx_fifo_empty_i(tx_fifo_empty_i),
           .tx_fifo_full_i(tx_fifo_full_i),
           .rx_fifo_full_i(rx_fifo_full_i),
           .xfr_complete_i(xfr_complete_i),
           .crc_ok_i(crc_ok_i),
           .int_status_o(int_status_o),
           .int_status_rst_i(int_status_rst_i)
       );

// Generating sd_clk clock
always
begin
    sd_clk=0;
    forever #(SD_TCLK/2) sd_clk = ~sd_clk;
end

initial
begin
    rst = 1;
    start_tx_i = 0;
    start_rx_i = 0;
    tx_fifo_empty_i = 0;
    tx_fifo_full_i = 0;
    rx_fifo_full_i = 0;
    xfr_complete_i = 1; //this signal is 0 only when serial_data_host is busy
    crc_ok_i = 0;
    int_status_rst_i = 0;
    
    $display("sd_data_master_tb start ...");
    
    #(3*SD_TCLK);
    rst = 0;
    assert(d_write_o == 0);
    assert(d_read_o == 0);
    assert(start_tx_fifo_o == 0);
    assert(start_rx_fifo_o == 0);
    assert(int_status_o == 0);
    #(3*SD_TCLK);
    assert(d_write_o == 0);
    assert(d_read_o == 0);
    assert(start_tx_fifo_o == 0);
    assert(start_rx_fifo_o == 0);
    assert(int_status_o == 0);
    
    //just check simple read and simple write, the rest is done by the sd_data_serial_host
    //////////////////////////////////////////////////////////////////////////////////////
    test_read(1);
    
    //write test
    /////////////////////////////////////////////////////////////////////
    test_write(1);
    
    //check fifo error during read / write
    //////////////////////////////////////////////////////////////////////
    start_tx_i = 1; //start filling tx fifo
    #SD_TCLK;
    start_tx_i = 0;
    wait(start_tx_fifo_o == 1);
    #(4.5*SD_TCLK);
    tx_fifo_full_i = 1; //tx fifo is full
    wait(d_write_o == 1);
    xfr_complete_i = 0;
    #(10.5*SD_TCLK);
    tx_fifo_full_i = 0;
    tx_fifo_empty_i = 1;
    #SD_TCLK;
    tx_fifo_empty_i = 0;
    assert(d_write_o == 1);
    assert(d_read_o == 1);
    wait(start_tx_fifo_o == 0);
    #(SD_TCLK/2);
    xfr_complete_i = 1;
    assert(start_rx_fifo_o == 0);
    assert(int_status_o == 4);
    
    //reset int status
    int_status_rst_i = 1;
    #SD_TCLK;
    int_status_rst_i = 0;
    assert(int_status_o == 0);
    
    //write test
    //////////////////////////////////////////////////////////////////////
    start_rx_i = 1; //start filling rx fifo and start sd_data_serial_host
    #SD_TCLK;
    start_rx_i = 0;
    wait(start_rx_fifo_o == 1 && d_read_o == 1);
    xfr_complete_i = 0;
    #(10.5*SD_TCLK);
    rx_fifo_full_i = 1;
    #SD_TCLK;
    rx_fifo_full_i = 0;
    assert(d_write_o == 1);
    assert(d_read_o == 1);
    wait(start_rx_fifo_o == 0);
    #(SD_TCLK/2);
    xfr_complete_i = 1;
    assert(start_rx_fifo_o == 0);
    assert(int_status_o == 4);
    
    //reset int status
    int_status_rst_i = 1;
    #SD_TCLK;
    int_status_rst_i = 0;
    assert(int_status_o == 0);
    
    //write crc not ok
    //////////////////////////////////////////////////////////////////////
    test_read(0);
    
    //read crc not ok
    //////////////////////////////////////////////////////////////////////
    test_write(0);

    #(10*SD_TCLK) $display("sd_data_master_tb finish ...");
    $finish;
    
end

endmodule

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.