//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// WISHBONE SD Card Controller IP Core ////
|
//// WISHBONE SD Card Controller IP Core ////
|
//// ////
|
//// ////
|
//// sd_data_serial_host_tb.sv ////
|
//// sd_data_serial_host_tb.sv ////
|
//// ////
|
//// ////
|
//// This file is part of the WISHBONE SD Card ////
|
//// This file is part of the WISHBONE SD Card ////
|
//// Controller IP Core project ////
|
//// Controller IP Core project ////
|
//// http://opencores.org/project,sd_card_controller ////
|
//// http://opencores.org/project,sd_card_controller ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// testbench for sd_data_serial_host module ////
|
//// testbench for sd_data_serial_host module ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2013 Authors ////
|
//// Copyright (C) 2013 Authors ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
`include "sd_defines.h"
|
`include "sd_defines.h"
|
|
|
module sd_data_serial_host_tb();
|
module sd_data_serial_host_tb();
|
|
|
parameter SD_TCLK = 20; // 50 MHz -> timescale 1ns
|
parameter SD_TCLK = 20; // 50 MHz -> timescale 1ns
|
parameter DATA_IDLE = 4'hf;
|
parameter DATA_IDLE = 4'hf;
|
parameter DATA_START = 4'h0;
|
parameter DATA_START = 4'h0;
|
parameter DATA_END = 4'hf;
|
parameter DATA_END = 4'hf;
|
|
|
reg sd_clk;
|
reg sd_clk;
|
reg rst;
|
reg rst;
|
//Tx Fifo
|
//Tx Fifo
|
reg [31:0] data_in;
|
reg [31:0] data_in;
|
wire rd;
|
wire rd;
|
//Rx Fifo
|
//Rx Fifo
|
wire[31:0] data_out;
|
wire[31:0] data_out;
|
wire we;
|
wire we;
|
//tristate data
|
//tristate data
|
wire DAT_oe_o;
|
wire DAT_oe_o;
|
wire [3:0] DAT_dat_o;
|
wire [3:0] DAT_dat_o;
|
reg [3:0] DAT_dat_i;
|
reg [3:0] DAT_dat_i;
|
//Controll signals
|
//Controll signals
|
reg [`BLKSIZE_W-1:0] blksize;
|
reg [`BLKSIZE_W-1:0] blksize;
|
reg bus_4bit;
|
reg bus_4bit;
|
reg [`BLKCNT_W-1:0] blkcnt;
|
reg [`BLKCNT_W-1:0] blkcnt;
|
reg [1:0] start;
|
reg [1:0] start;
|
wire sd_data_busy;
|
wire sd_data_busy;
|
wire busy;
|
wire busy;
|
wire crc_ok;
|
wire crc_ok;
|
|
|
integer fifo_send_data[0:3] = {32'h12345678, 32'haabbccdd, 32'h9abcdef0, 32'h55aacc33};
|
integer fifo_send_data[0:3] = {32'h12345678, 32'haabbccdd, 32'h9abcdef0, 32'h55aacc33};
|
//integer fifo_send_data[0:0] = {32'hffffffff};
|
//integer fifo_send_data[0:0] = {32'hffffffff};
|
reg [1:0] fifo_idx = 0;
|
reg [1:0] fifo_idx = 0;
|
integer fifo_receive_data[0:3] = {32'h00010203, 32'ha0a1a2a3, 32'hdeadbeef, 32'hbad00dad};
|
integer fifo_receive_data[0:3] = {32'h00010203, 32'ha0a1a2a3, 32'hdeadbeef, 32'hbad00dad};
|
|
|
function [3:0] get_1or4_bits;
|
function [3:0] get_1or4_bits;
|
input [3:0] data;
|
input [3:0] data;
|
input integer bits;
|
input integer bits;
|
begin
|
begin
|
if (bits == 1)
|
if (bits == 1)
|
get_1or4_bits = {3'b111, data[0]};
|
get_1or4_bits = {3'b111, data[0]};
|
else
|
else
|
get_1or4_bits = data;
|
get_1or4_bits = data;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
function integer crc16;
|
function integer crc16;
|
input integer crc_in;
|
input integer crc_in;
|
input bit inb;
|
input bit inb;
|
begin
|
begin
|
inb = inb ^ crc_in[0];
|
inb = inb ^ crc_in[0];
|
crc16 = crc_in >> 1;
|
crc16 = crc_in >> 1;
|
crc16 = crc16 ^ (16'h8408 & {16{inb}});
|
crc16 = crc16 ^ (16'h8408 & {16{inb}});
|
end
|
end
|
endfunction
|
endfunction
|
|
|
task sd_card_send;
|
task sd_card_send;
|
input integer bytes;
|
input integer bytes;
|
input integer blocks;
|
input integer blocks;
|
input integer width;
|
input integer width;
|
input bit crc_failure;
|
input bit crc_failure;
|
integer cycles;
|
integer cycles;
|
integer i, j;
|
integer i, j;
|
integer data_idx;
|
integer data_idx;
|
integer shift;
|
integer shift;
|
integer crc[0:3];
|
integer crc[0:3];
|
reg [3:0] crc_out;
|
reg [3:0] crc_out;
|
begin
|
begin
|
assert(width == 1 || width == 4) else $stop;
|
assert(width == 1 || width == 4) else $stop;
|
while (blocks+1) begin
|
while (blocks+1) begin
|
cycles = bytes*8/width;
|
cycles = bytes*8/width;
|
crc = {0, 0, 0, 0};
|
crc = {0, 0, 0, 0};
|
//start bits
|
//start bits
|
DAT_dat_i = get_1or4_bits(DATA_START, width);
|
DAT_dat_i = get_1or4_bits(DATA_START, width);
|
#SD_TCLK;
|
#SD_TCLK;
|
//data bits
|
//data bits
|
for (i=0; i
|
for (i=0; i
|
data_idx = (i*width/32)%$size(fifo_receive_data);
|
data_idx = (i*width/32)%$size(fifo_receive_data);
|
shift = (32-width)-((i*width)%32);
|
shift = (32-width)-((i*width)%32);
|
DAT_dat_i = get_1or4_bits(fifo_receive_data[data_idx] >> shift, width);
|
DAT_dat_i = get_1or4_bits(fifo_receive_data[data_idx] >> shift, width);
|
for (j=0; j<4; j++)
|
for (j=0; j<4; j++)
|
crc[j] = crc16(crc[j], DAT_dat_i[j]);
|
crc[j] = crc16(crc[j], DAT_dat_i[j]);
|
#SD_TCLK;
|
#SD_TCLK;
|
end
|
end
|
//crc bits
|
//crc bits
|
for (i=0; i<16; i++) begin
|
for (i=0; i<16; i++) begin
|
for (j=0; j<4; j++)
|
for (j=0; j<4; j++)
|
crc_out[j] = crc[j] >> i;
|
crc_out[j] = crc[j] >> i;
|
DAT_dat_i = get_1or4_bits(crc_failure ? 0 : crc_out, width);
|
DAT_dat_i = get_1or4_bits(crc_failure ? 0 : crc_out, width);
|
#SD_TCLK;
|
#SD_TCLK;
|
end
|
end
|
//stop bits
|
//stop bits
|
DAT_dat_i = get_1or4_bits(DATA_END, width);
|
DAT_dat_i = get_1or4_bits(DATA_END, width);
|
#SD_TCLK;
|
#SD_TCLK;
|
DAT_dat_i = get_1or4_bits(DATA_IDLE, width);
|
DAT_dat_i = get_1or4_bits(DATA_IDLE, width);
|
#SD_TCLK;
|
#SD_TCLK;
|
if (blocks)
|
if (blocks)
|
assert(busy == 1);
|
assert(busy == 1);
|
assert(crc_ok == !crc_failure);
|
assert(crc_ok == !crc_failure);
|
blocks--;
|
blocks--;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task sd_card_receive;
|
task sd_card_receive;
|
input integer bytes;
|
input integer bytes;
|
input integer blocks;
|
input integer blocks;
|
input integer width;
|
input integer width;
|
input [2:0] crc_status;
|
input [2:0] crc_status;
|
integer cycles;
|
integer cycles;
|
integer i, j;
|
integer i, j;
|
integer received_data;
|
integer received_data;
|
integer data_idx;
|
integer data_idx;
|
integer shift;
|
integer shift;
|
integer crc[0:3];
|
integer crc[0:3];
|
integer crc_in[0:3];
|
integer crc_in[0:3];
|
//reg [3:0] crc_out;
|
//reg [3:0] crc_out;
|
begin
|
begin
|
assert(width == 1 || width == 4) else $stop;
|
assert(width == 1 || width == 4) else $stop;
|
cycles = bytes*8/width;
|
cycles = bytes*8/width;
|
|
|
while(blocks+1) begin
|
while(blocks+1) begin
|
received_data = 0;
|
received_data = 0;
|
crc = {0, 0, 0, 0};
|
crc = {0, 0, 0, 0};
|
crc_in = {0, 0, 0, 0};
|
crc_in = {0, 0, 0, 0};
|
//wait for start bits
|
//wait for start bits
|
wait (DAT_dat_o == get_1or4_bits(DATA_START, width));
|
wait (DAT_dat_o == get_1or4_bits(DATA_START, width));
|
assert(DAT_oe_o == 1);
|
assert(DAT_oe_o == 1);
|
#(SD_TCLK/2);
|
#(SD_TCLK/2);
|
//data bits
|
//data bits
|
for (i=0; i
|
for (i=0; i
|
#SD_TCLK;
|
#SD_TCLK;
|
shift = (32-width)-((i*width)%32);
|
shift = (32-width)-((i*width)%32);
|
for (j=0; j
|
for (j=0; j
|
received_data[shift+j] = DAT_dat_o[j];
|
received_data[shift+j] = DAT_dat_o[j];
|
assert(DAT_oe_o == 1);
|
assert(DAT_oe_o == 1);
|
if ((i*width)%32 == (32-width)) begin
|
if ((i*width)%32 == (32-width)) begin
|
data_idx = (i*width/32)%$size(fifo_send_data);
|
data_idx = (i*width/32)%$size(fifo_send_data);
|
assert(fifo_send_data[data_idx] == received_data);
|
assert(fifo_send_data[data_idx] == received_data);
|
end
|
end
|
for (j=0; j
|
for (j=0; j
|
crc[j] = crc16(crc[j], DAT_dat_o[j]);
|
crc[j] = crc16(crc[j], DAT_dat_o[j]);
|
end
|
end
|
//crc bits
|
//crc bits
|
for (i=0; i<16; i++) begin
|
for (i=0; i<16; i++) begin
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(DAT_oe_o == 1);
|
assert(DAT_oe_o == 1);
|
for (j=0; j
|
for (j=0; j
|
crc_in[j][i] = DAT_dat_o[j];
|
crc_in[j][i] = DAT_dat_o[j];
|
end
|
end
|
for (i=0; i
|
for (i=0; i
|
assert(crc_in[i] == crc[i]);
|
assert(crc_in[i] == crc[i]);
|
//stop bits
|
//stop bits
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(DAT_oe_o == 1);
|
assert(DAT_oe_o == 1);
|
assert(DAT_dat_o == DATA_END);
|
assert(DAT_dat_o == DATA_END);
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(DAT_oe_o == 0);
|
assert(DAT_oe_o == 0);
|
#(2*SD_TCLK);
|
#(2*SD_TCLK);
|
//crc status
|
//crc status
|
//start bit
|
//start bit
|
DAT_dat_i = get_1or4_bits(DATA_START, 1);
|
DAT_dat_i = get_1or4_bits(DATA_START, 1);
|
#SD_TCLK;
|
#SD_TCLK;
|
//crc status bits
|
//crc status bits
|
for (i=0; i<$size(crc_status); i++) begin
|
for (i=0; i<$size(crc_status); i++) begin
|
DAT_dat_i = {3'h7, crc_status[i]};
|
DAT_dat_i = {3'h7, crc_status[i]};
|
#SD_TCLK;
|
#SD_TCLK;
|
end
|
end
|
//stop bit
|
//stop bit
|
DAT_dat_i = get_1or4_bits(DATA_END, 1);
|
DAT_dat_i = get_1or4_bits(DATA_END, 1);
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(sd_data_busy == 0);
|
assert(sd_data_busy == 0);
|
//busy bit
|
//busy bit
|
DAT_dat_i = {3'h7, 1'b0};
|
DAT_dat_i = {3'h7, 1'b0};
|
#(2*SD_TCLK);
|
#(2*SD_TCLK);
|
assert(sd_data_busy == 1);
|
assert(sd_data_busy == 1);
|
if (blocks)
|
if (blocks)
|
assert(busy == 1);
|
assert(busy == 1);
|
if (crc_status == 3'b010)
|
if (crc_status == 3'b010)
|
assert(crc_ok == 1);
|
assert(crc_ok == 1);
|
else
|
else
|
assert(crc_ok == 0);
|
assert(crc_ok == 0);
|
#(10*SD_TCLK);
|
#(10*SD_TCLK);
|
DAT_dat_i = DATA_IDLE;
|
DAT_dat_i = DATA_IDLE;
|
blocks--;
|
blocks--;
|
end
|
end
|
#SD_TCLK;
|
#SD_TCLK;
|
end
|
end
|
endtask
|
endtask
|
|
|
task check_fifo_write;
|
task check_fifo_write;
|
input integer bytes;
|
input integer bytes;
|
input integer blocks;
|
input integer blocks;
|
input integer width;
|
input integer width;
|
integer cycles, i, j;
|
integer cycles, i, j;
|
begin
|
begin
|
assert(width == 1 || width == 4) else $stop;
|
assert(width == 1 || width == 4) else $stop;
|
cycles = bytes/4;
|
cycles = bytes/4;
|
while (blocks+1) begin
|
while (blocks+1) begin
|
wait (we == 1);
|
wait (we == 1);
|
#(SD_TCLK/2);
|
#(SD_TCLK/2);
|
assert(data_out == fifo_receive_data[0]);
|
assert(data_out == fifo_receive_data[0]);
|
for (i=1; i
|
for (i=1; i
|
for (j=0; j<32/width-1; j++) begin
|
for (j=0; j<32/width-1; j++) begin
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(we == 0);
|
assert(we == 0);
|
end
|
end
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(we == 1);
|
assert(we == 1);
|
assert(data_out == fifo_receive_data[i%$size(fifo_receive_data)]);
|
assert(data_out == fifo_receive_data[i%$size(fifo_receive_data)]);
|
end
|
end
|
blocks--;
|
blocks--;
|
#SD_TCLK;
|
#SD_TCLK;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task check_fifo_read;
|
task check_fifo_read;
|
input integer bytes;
|
input integer bytes;
|
input integer blocks;
|
input integer blocks;
|
input integer width;
|
input integer width;
|
integer cycles, i, j;
|
integer cycles, i, j;
|
begin
|
begin
|
assert(width == 1 || width == 4) else $stop;
|
assert(width == 1 || width == 4) else $stop;
|
cycles = bytes/4;
|
cycles = bytes/4;
|
while (blocks+1) begin
|
while (blocks+1) begin
|
wait (rd == 1);
|
wait (rd == 1);
|
#(SD_TCLK/2);
|
#(SD_TCLK/2);
|
assert(rd == 1);
|
assert(rd == 1);
|
|
//read delay !!!
|
|
#(2*SD_TCLK);
|
data_in = fifo_send_data[1%$size(fifo_send_data)];
|
data_in = fifo_send_data[1%$size(fifo_send_data)];
|
for (i=2; i
|
for (i=2; i
|
for (j=0; j<32/width-1; j++) begin
|
for (j=0; j<32/width-1; j++) begin
|
#SD_TCLK;
|
#SD_TCLK;
|
|
if (j == 32/width-3)
|
|
assert(rd == 1);
|
|
else
|
assert(rd == 0);
|
assert(rd == 0);
|
end
|
end
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(rd == 1);
|
assert(rd == 0);
|
data_in = fifo_send_data[i%$size(fifo_send_data)];
|
data_in = fifo_send_data[i%$size(fifo_send_data)];
|
end
|
end
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(rd == 0);
|
assert(rd == 0);
|
data_in = fifo_send_data[0];
|
data_in = fifo_send_data[0];
|
blocks--;
|
blocks--;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task read_test;
|
task read_test;
|
input integer bsize;
|
input integer bsize;
|
input integer bcnt;
|
input integer bcnt;
|
input integer b_4bit;
|
input integer b_4bit;
|
input bit crc_failure;
|
input bit crc_failure;
|
begin
|
begin
|
blksize = bsize;
|
blksize = bsize;
|
blkcnt = bcnt;
|
blkcnt = bcnt;
|
bus_4bit = b_4bit;
|
bus_4bit = b_4bit;
|
start = 2; //read
|
start = 2; //read
|
#SD_TCLK;
|
#SD_TCLK;
|
blksize = 0;
|
blksize = 0;
|
bus_4bit = 0;
|
bus_4bit = 0;
|
blkcnt = 0;
|
blkcnt = 0;
|
start = 0;
|
start = 0;
|
assert(busy == 1);
|
assert(busy == 1);
|
|
|
#(20*SD_TCLK);
|
#(20*SD_TCLK);
|
|
|
fork
|
fork
|
sd_card_send(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1, crc_failure);
|
sd_card_send(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1, crc_failure);
|
check_fifo_write(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1);
|
check_fifo_write(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1);
|
join
|
join
|
|
|
#SD_TCLK;
|
#SD_TCLK;
|
assert(busy == 0);
|
assert(busy == 0);
|
end
|
end
|
endtask
|
endtask
|
|
|
task write_test;
|
task write_test;
|
input integer bsize;
|
input integer bsize;
|
input integer bcnt;
|
input integer bcnt;
|
input integer b_4bit;
|
input integer b_4bit;
|
input bit crc_failure;
|
input bit crc_failure;
|
begin
|
begin
|
blksize = bsize;
|
blksize = bsize;
|
blkcnt = bcnt;
|
blkcnt = bcnt;
|
bus_4bit = b_4bit;
|
bus_4bit = b_4bit;
|
start = 1; //write
|
start = 1; //write
|
#SD_TCLK;
|
#SD_TCLK;
|
blksize = 0;
|
blksize = 0;
|
bus_4bit = 0;
|
bus_4bit = 0;
|
blkcnt = 0;
|
blkcnt = 0;
|
start = 0;
|
start = 0;
|
assert(busy == 1);
|
assert(busy == 1);
|
|
|
fork
|
fork
|
check_fifo_read(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1);
|
check_fifo_read(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1);
|
sd_card_receive(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1, crc_failure ? 3'b101 : 3'b010);
|
sd_card_receive(bsize, crc_failure ? 0 : bcnt, b_4bit ? 4 : 1, crc_failure ? 3'b101 : 3'b010);
|
join
|
join
|
|
|
#(2*SD_TCLK);
|
#(2*SD_TCLK);
|
assert(busy == 0);
|
assert(busy == 0);
|
end
|
end
|
endtask
|
endtask
|
|
|
sd_data_serial_host sd_data_serial_host_dut(
|
sd_data_serial_host sd_data_serial_host_dut(
|
.sd_clk (sd_clk),
|
.sd_clk (sd_clk),
|
.rst (rst),
|
.rst (rst),
|
.data_in (data_in),
|
.data_in (data_in),
|
.rd (rd),
|
.rd (rd),
|
.data_out (data_out),
|
.data_out (data_out),
|
.we (we),
|
.we (we),
|
.DAT_oe_o (DAT_oe_o),
|
.DAT_oe_o (DAT_oe_o),
|
.DAT_dat_o (DAT_dat_o),
|
.DAT_dat_o (DAT_dat_o),
|
.DAT_dat_i (DAT_dat_i),
|
.DAT_dat_i (DAT_dat_i),
|
.blksize (blksize),
|
.blksize (blksize),
|
.bus_4bit (bus_4bit),
|
.bus_4bit (bus_4bit),
|
.blkcnt (blkcnt),
|
.blkcnt (blkcnt),
|
.start (start),
|
.start (start),
|
.sd_data_busy (sd_data_busy),
|
.sd_data_busy (sd_data_busy),
|
.busy (busy),
|
.busy (busy),
|
.crc_ok (crc_ok)
|
.crc_ok (crc_ok)
|
);
|
);
|
|
|
// Generating WB_CLK_I clock
|
// Generating WB_CLK_I clock
|
always
|
always
|
begin
|
begin
|
sd_clk=0;
|
sd_clk=0;
|
forever #(SD_TCLK/2) sd_clk = ~sd_clk;
|
forever #(SD_TCLK/2) sd_clk = ~sd_clk;
|
end
|
end
|
|
|
initial
|
initial
|
begin
|
begin
|
rst = 1;
|
rst = 1;
|
DAT_dat_i = DATA_IDLE;
|
DAT_dat_i = DATA_IDLE;
|
data_in = fifo_send_data[0];
|
data_in = fifo_send_data[0];
|
blksize = 0;
|
blksize = 0;
|
bus_4bit = 0;
|
bus_4bit = 0;
|
blkcnt = 0;
|
blkcnt = 0;
|
start = 0;
|
start = 0;
|
|
|
$display("sd_data_serial_host_tb start ...");
|
$display("sd_data_serial_host_tb start ...");
|
|
|
#(3*SD_TCLK);
|
#(3*SD_TCLK);
|
rst = 0;
|
rst = 0;
|
|
|
assert(rd == 0);
|
assert(rd == 0);
|
assert(we == 0);
|
assert(we == 0);
|
assert(DAT_oe_o == 0);
|
assert(DAT_oe_o == 0);
|
assert(busy == 0);
|
assert(busy == 0);
|
|
|
#(3*SD_TCLK);
|
#(3*SD_TCLK);
|
|
|
//tests with 1-bit mode and 4-bit mode
|
//tests with 1-bit mode and 4-bit mode
|
//single block read and single block write
|
//single block read and single block write
|
//multiple block read and multiple block write
|
//multiple block read and multiple block write
|
//test with bad crc (wrong crc during read, wrong rcr in response)
|
//test with bad crc (wrong crc during read, wrong rcr in response)
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//1-bit single block read
|
//1-bit single block read
|
read_test(64, 0, 0, 0);
|
read_test(64, 0, 0, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//1-bit single block write
|
//1-bit single block write
|
write_test(128, 0, 0, 0);
|
write_test(128, 0, 0, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//1-bit multiple block read
|
//1-bit multiple block read
|
read_test(32, 3, 0, 0);
|
read_test(32, 3, 0, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//1-bit multiple block write
|
//1-bit multiple block write
|
write_test(16, 8, 0, 0);
|
write_test(16, 8, 0, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
// 4 - bit
|
// 4 - bit
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//4-bit single block read
|
//4-bit single block read
|
read_test(256, 0, 1, 0);
|
read_test(256, 0, 1, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//4-bit single block write
|
//4-bit single block write
|
write_test(512, 0, 1, 0);
|
write_test(512, 0, 1, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//4-bit multiple block read
|
//4-bit multiple block read
|
read_test(8, 17, 1, 0);
|
read_test(8, 17, 1, 0);
|
|
|
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
//4-bit multiple block write
|
//4-bit multiple block write
|
write_test(4, 32, 1, 0);
|
write_test(4, 32, 1, 0);
|
|
|
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
// wierd configurations
|
// wierd configurations
|
//4-bit single block read
|
//4-bit single block read
|
read_test(13, 0, 1, 0);
|
read_test(13, 0, 1, 0);
|
write_test(19, 0, 1, 0);
|
write_test(19, 0, 1, 0);
|
|
|
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
// bad crc
|
// bad crc
|
//
|
//
|
read_test(32, 0, 1, 1);
|
read_test(32, 0, 1, 1);
|
read_test(16, 3, 1, 1);
|
read_test(16, 3, 1, 1);
|
write_test(18, 0, 1, 1);
|
write_test(18, 0, 1, 1);
|
write_test(64, 2, 1, 1);
|
write_test(64, 2, 1, 1);
|
read_test(32, 0, 1, 0);
|
read_test(32, 0, 1, 0);
|
read_test(16, 3, 1, 0);
|
read_test(16, 3, 1, 0);
|
write_test(18, 0, 1, 0);
|
write_test(18, 0, 1, 0);
|
write_test(64, 2, 1, 0);
|
write_test(64, 2, 1, 0);
|
|
|
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
// TODO: xfer stopped in the middle
|
// TODO: xfer stopped in the middle
|
|
|
#(100*SD_TCLK) $display("sd_data_serial_host_tb finish ...");
|
#(100*SD_TCLK) $display("sd_data_serial_host_tb finish ...");
|
$finish;
|
$finish;
|
|
|
end
|
end
|
|
|
|
|