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

Subversion Repositories uart16550

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 92 to Rev 93
    Reverse comparison

Rev 92 → Rev 93

/trunk/bench/verilog/uart_log.v
0,0 → 1,206
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_log.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - Miha Dolenc, mihad@opencores.org ////
//// - Tadej Markovic, tadejm@opencores.org ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
//// Tadej Markovic, tadejm@opencores.org ////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module uart_log;
 
 
parameter testcase_name = "";
 
integer report_log_file_desc;
integer verbose_log_file_desc;
 
reg free;
integer tests_ok;
integer tests_failed;
 
initial free = 1;
initial tests_ok = 0;
initial tests_failed = 0;
 
task start_log;
output ok_o;
begin
report_log_file_desc = $fopen({"../log/", testcase_name, "_report.log"});
verbose_log_file_desc = $fopen({"../log/", testcase_name, "_verbose.log"});
if ((report_log_file_desc == 0) || (verbose_log_file_desc == 0))
ok_o = 1'b0;
else
ok_o = 1'b1;
end
endtask // start_log
 
task end_log;
begin
report_add_delimiter;
$fdisplay(report_log_file_desc, "TEST CASE execution summary:");
$fdisplay(report_log_file_desc, "Number of tests PASSED=%0d", tests_ok);
$fdisplay(report_log_file_desc, "Number of tests FAILED=%0d", tests_failed);
$fdisplay(report_log_file_desc, " Simulation End Time: %t", $time);
report_add_delimiter;
$fclose(report_log_file_desc);
$fclose(verbose_log_file_desc);
end
endtask // end_log
 
task report_test_name;
input [1599:0] test_i;
begin
report_add_delimiter;
$fdisplay(report_log_file_desc, "%0s", test_i);
end
endtask // report_test_name
 
task report_test_failed;
input [7999:0] message_i;
begin
$fdisplay(report_log_file_desc, " FAILED!");
$fdisplay(report_log_file_desc, " Failure message: %0s.", message_i);
$fdisplay(report_log_file_desc, " Simulation Time: %t", $time);
end
endtask // report_test_failed
 
task report_test_ok;
begin
$fdisplay(report_log_file_desc, " PASSED!");
$fdisplay(report_log_file_desc, " Simulation Time: %t", $time);
end
endtask // report_test_ok
 
task report_add_delimiter;
begin
$fdisplay(report_log_file_desc, "");
$fdisplay(report_log_file_desc, "%0s", {75{"-"}});
$fdisplay(report_log_file_desc, "");
end
endtask // report_add_delimiter
 
task report_add_text;
input [7999:0] text_i;
begin
$fdisplay(report_log_file_desc, " %0s", text_i);
end
endtask // report_add_text
 
task verbose_test_name;
input [1599:0] test_i;
begin
free = 0;
$fdisplay(verbose_log_file_desc, "");
$fdisplay(verbose_log_file_desc, "%0s", {75{"-"}});
$fdisplay(verbose_log_file_desc, "- %0s", test_i);
$fdisplay(verbose_log_file_desc, "%0s", {75{"-"}});
$fdisplay(verbose_log_file_desc, "");
free = 1;
end
endtask // verbose_test_name
 
task verbose_severe_err;
input [7999:0] time_i;
input [7999:0] severe_error_i;
begin
free = 0;
$fdisplay(verbose_log_file_desc, "%0s", time_i);
$fdisplay(verbose_log_file_desc, "*E, Reporting severe error:");
$fdisplay(verbose_log_file_desc, " %0s", severe_error_i);
free = 1;
end
endtask // verbose_severe_err
 
task verbose_err;
input [7999:0] time_i;
input [7999:0] error_i;
begin
free = 0;
$fdisplay(verbose_log_file_desc, "%0s", time_i);
$fdisplay(verbose_log_file_desc, "*E, %0s", error_i);
free = 1;
end
endtask // verbose_err
 
task verbose_wrn;
input [7999:0] time_i;
input [7999:0] warning_i;
begin
free = 0;
$fdisplay(verbose_log_file_desc, "%0s", time_i);
$fdisplay(verbose_log_file_desc, "*W, %0s", warning_i);
free = 1;
end
endtask // verbose_wrn
 
task verbose_msg;
input [7999:0] time_i;
input [7999:0] message_i;
begin
free = 0;
$fdisplay(verbose_log_file_desc, "%0s", time_i);
$fdisplay(verbose_log_file_desc, "*N, %0s", message_i);
free = 1;
end
endtask // verbose_msg
 
task verbose_val;
input [7999:0] time_i;
input [7999:0] message_i;
input [31:0] value_i;
begin
free = 0;
$fdisplay(verbose_log_file_desc, "%0s", time_i);
$fdisplay(verbose_log_file_desc, "*N, %0s %0h.", message_i, value_i);
free = 1;
end
endtask // verbose_val
 
 
endmodule // uart_log
 
/trunk/bench/verilog/uart_wb_utilities.v
0,0 → 1,359
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_wb_utilities.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - tadej@opencores.org (Tadej Markovic) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`include "uart_defines.v"
`include "uart_testbench_defines.v"
`include "wb_model_defines.v"
`include "timescale.v"
 
module uart_wb_utilities;
 
// Single read/write TASKs
//########################
 
// SINGLE_READ
task single_read;
input [`UART_ADDR_WIDTH-1:0] read_adr_i;
reg [3:0] read_sel_i;
reg `WBM_MODEL_READ_IN_TYPE read_stim;
reg `WBM_MODEL_READ_OUT_TYPE read_result;
integer master_waits;
integer slave_waits;
integer num_of_reads;
reg fast_b2b;
begin
read_sel_i = 4'hF;
testbench.i_wb_master_model.next_read_adr = read_adr_i;
testbench.i_wb_master_model.next_read_sel = read_sel_i;
testbench.i_wb_master_model.next_read_cti = 3'b000; // Clasic WB
testbench.i_wb_master_model.next_read_bte = $random; // Don't care hwen Clasic WB
master_waits = {$random} % 13;
slave_waits = 4;
num_of_reads = 1;
fast_b2b = 1'b0;
read_stim`WBM_MODEL_READ_WAITS = master_waits;
read_stim`WBM_MODEL_READ_ALLOWED_SLAVE_WAITS = slave_waits;
read_stim`WBM_MODEL_READ_LAST = (num_of_reads == 1);
read_stim`WBM_MODEL_READ_FAST_B2B = fast_b2b;
// Start read
testbench.i_wb_master_model.start_read(read_stim, read_result);
// ACK response
if (read_result`WBM_MODEL_READ_SLAVE_ACK !== 1'b1)
begin
`TC_ERROR("Wishbone master model did not receive expected transfer termination from the design.");
end
//
if (read_result`WBM_MODEL_READ_STIM_ERR !== 1'b0)
begin
`TC_ERROR("No reads done since design's wishbone slave interface responded with an error.");
end
//
if (read_result`WBM_MODEL_READ_DESIGN_ERR !== 1'b0)
begin
`TC_ERROR("Wishbone master model detected a design response error during single read access.");
end
end
endtask // single_read
 
// SINGLE_WRITE
task single_write;
input [`UART_ADDR_WIDTH-1:0] write_adr_i;
input [`UART_DATA_WIDTH-1:0] write_dat_i;
reg [3:0] write_sel_i;
reg `WBM_MODEL_WRITE_IN_TYPE write_stim;
reg `WBM_MODEL_WRITE_OUT_TYPE write_result;
integer master_waits;
integer slave_waits;
integer num_of_writes;
reg fast_b2b;
begin
write_sel_i = 4'hF;
testbench.i_wb_master_model.next_write_adr = write_adr_i;
testbench.i_wb_master_model.next_write_sel = write_sel_i;
testbench.i_wb_master_model.next_write_dat = write_dat_i;
testbench.i_wb_master_model.next_write_cti = 3'b000; // Clasic WB
testbench.i_wb_master_model.next_write_bte = $random; // Don't care hwen Clasic WB
master_waits = {$random} % 13;
slave_waits = 4;
num_of_writes = 1;
fast_b2b = 1'b0;
write_stim`WBM_MODEL_WRITE_WAITS = master_waits;
write_stim`WBM_MODEL_WRITE_ALLOWED_SLAVE_WAITS = slave_waits;
write_stim`WBM_MODEL_WRITE_LAST = (num_of_writes == 1);
write_stim`WBM_MODEL_WRITE_FAST_B2B = fast_b2b;
// Start write
testbench.i_wb_master_model.start_write(write_stim, write_result);
// ACK response
if (write_result`WBM_MODEL_WRITE_SLAVE_ACK !== 1'b1)
begin
`TC_ERROR("Wishbone master model did not receive expected transfer termination from the design.");
end
//
if (write_result`WBM_MODEL_WRITE_STIM_ERR !== 1'b0)
begin
`TC_ERROR("No writes done since wishbone master model reported an error.");
end
//
if (write_result`WBM_MODEL_WRITE_DESIGN_ERR !== 1'b0)
begin
`TC_ERROR("Wishbone master model detected a design response error during single write access.");
end
end
endtask // single_write
 
// Char read/write TASKs
//######################
 
// READ_CHAR
task read_char;
begin
if (testbench.lcr_reg[7] === 1'b1) // dlab == 1
begin
`UTILS_ERROR("READING of CHAR from RB Register NOT possible, since DLAB in LC Register is set.");
end
else
begin
`UTILS_MSG("READING of CHAR from UART's RB Register.");
single_read(`UART_REG_RB);
`UTILS_VAL1("Read RBR =", testbench.i_wb_master_model.read_dat);
end
end
endtask // read_char
 
// WRITE_CHAR
task write_char;
input [7:0] char_i;
begin
if (testbench.lcr_reg[7] === 1'b1) // dlab == 1
begin
`UTILS_ERROR("WRITING CHAR to TR Register NOT possible, since DLAB in LC Register is set.");
end
else
begin
`UTILS_MSG("WRITING CHAR to UART's TR Register.");
single_write(`UART_REG_TR, char_i);
`UTILS_VAL1("Write TRR =", testbench.i_wb_master_model.write_dat);
end
end
endtask // write_char
 
// Register read/write TASKs
//##########################
 
// READ_IER - adr 1
task read_ier;
begin
if (testbench.lcr_reg[7] === 1'b1) // dlab == 1
begin
`UTILS_ERROR("READING of IE Register NOT possible, since DLAB in LC Register is set.");
end
else
begin
`UTILS_MSG("READING UART's IE Register.");
single_read(`UART_REG_IE);
`UTILS_VAL1("Read IER =", testbench.i_wb_master_model.read_dat);
end
end
endtask // read_ier
 
// WRITE_IER - adr 1
task write_ier;
input [7:0] data_i;
begin
if (testbench.lcr_reg[7] === 1'b1) // dlab == 1
begin
`UTILS_ERROR("WRITING to IE Register NOT possible, since DLAB in LC Register is set.");
end
else
begin
`UTILS_MSG("WRITING UART's IE Register.");
single_write(`UART_REG_IE, data_i);
`UTILS_VAL1("Write IER =", testbench.i_wb_master_model.write_dat);
end
end
endtask // write_ier
 
// READ_IIR - adr 2
task read_iir;
begin
`UTILS_MSG("READING UART's II Register.");
single_read(`UART_REG_II);
`UTILS_VAL1("Read IIR =", testbench.i_wb_master_model.read_dat);
end
endtask // read_iir
 
// WRITE_FCR - adr 2
task write_fcr;
input [7:0] data_i;
begin
`UTILS_MSG("WRITING UART's FC Register.");
single_write(`UART_REG_FC, data_i);
`UTILS_VAL1("Write FCR =", testbench.i_wb_master_model.write_dat);
end
endtask // write_fcr
 
// READ_LCR - adr 3
task read_lcr;
begin
`UTILS_MSG("READING UART's LC Register.");
single_read(`UART_REG_LC);
`UTILS_VAL1("Read LCR =", testbench.i_wb_master_model.read_dat);
end
endtask // read_lcr
 
// WRITE_LCR - adr 3
task write_lcr;
input [7:0] data_i;
begin
`UTILS_MSG("WRITING UART's LC Register.");
single_write(`UART_REG_LC, data_i);
`UTILS_VAL1("Write LCR =", testbench.i_wb_master_model.write_dat);
end
endtask // write_lcr
 
// WRITE_MCR - adr 4
task write_mcr;
input [7:0] data_i;
begin
`UTILS_MSG("WRITING UART's MC Register.");
single_write(`UART_REG_MC, data_i);
`UTILS_VAL1("Write MCR =", testbench.i_wb_master_model.write_dat);
end
endtask // write_mcr
 
// READ_LSR - adr 5
task read_lsr;
begin
`UTILS_MSG("READING UART's LS Register.");
single_read(`UART_REG_LS);
`UTILS_VAL1("Read LSR =", testbench.i_wb_master_model.read_dat);
end
endtask // read_lsr
 
// READ_MSR - adr 6
task read_msr;
begin
`UTILS_MSG("READING UART's MS Register.");
single_read(`UART_REG_MS);
`UTILS_VAL1("Read MSR =", testbench.i_wb_master_model.read_dat);
end
endtask // read_msr
 
// READ_DLR - adr 0, 1
task read_dlr;
begin
if (testbench.lcr_reg[7] === 1'b0) // dlab == 0
begin
// Setting DLAB
`UTILS_MSG("DLAB in LC Register is going to be 1.");
`UTILS_VAL1("Current LCR =", testbench.lcr_reg);
write_lcr(testbench.lcr_reg | 8'h80);
// Reading DL Register
`UTILS_MSG("READING UART's DL Register [15:8].");
single_read(`UART_REG_DL2);
`UTILS_VAL1("Read DLR [15:8] =", testbench.i_wb_master_model.read_dat);
`UTILS_MSG("READING UART's DL Register [ 7:0].");
single_read(`UART_REG_DL1);
`UTILS_VAL1("Read DLR [ 7:0] =", testbench.i_wb_master_model.read_dat);
// Resetting DLAB
`UTILS_MSG("DLAB in LC Register is going to be 0.");
write_lcr(testbench.lcr_reg & 8'h7F);
end
else
begin
`UTILS_MSG("DLAB in LC Register is already 1.");
`UTILS_VAL1("Current LCR =", testbench.lcr_reg);
// Reading DL Register
`UTILS_MSG("READING UART's DL Register [15:8].");
single_read(`UART_REG_DL2);
`UTILS_VAL1("Read DLR [15:8] =", testbench.i_wb_master_model.read_dat);
`UTILS_MSG("READING UART's DL Register [ 7:0].");
single_read(`UART_REG_DL1);
`UTILS_VAL1("Read DLR [ 7:0] =", testbench.i_wb_master_model.read_dat);
end
end
endtask // read_dlr
 
// WRITE_DLR - adr 0, 1
task write_dlr;
input [15:0] data_i;
begin
if (testbench.lcr_reg[7] === 1'b0) // dlab == 0
begin
// Setting DLAB
`UTILS_MSG("DLAB in LC Register is going to be 1.");
`UTILS_VAL1("Current LCR =", testbench.lcr_reg);
write_lcr(testbench.lcr_reg | 8'h80);
// Writing DL Register
`UTILS_MSG("WRITING UART's DL Register [15:8].");
single_write(`UART_REG_DL2, data_i[15:8]);
`UTILS_VAL1("Write DLR [15:8] =", testbench.i_wb_master_model.write_dat);
`UTILS_MSG("WRITING UART's DL Register [ 7:0].");
single_write(`UART_REG_DL1, data_i[ 7:0]);
`UTILS_VAL1("Write DLR [ 7:0] =", testbench.i_wb_master_model.write_dat);
// Resetting DLAB
`UTILS_MSG("DLAB in LC Register is going to be 0.");
write_lcr(testbench.lcr_reg & 8'h7F);
end
else
begin
`UTILS_MSG("DLAB in LC Register is already 1.");
`UTILS_VAL1("Current LCR =", testbench.lcr_reg);
// Writing DL Register
`UTILS_MSG("WRITING UART's DL Register [15:8].");
single_write(`UART_REG_DL2, data_i[15:8]);
`UTILS_VAL1("Write DLR [15:8] =", testbench.i_wb_master_model.write_dat);
`UTILS_MSG("WRITING UART's DL Register [ 7:0].");
single_write(`UART_REG_DL1, data_i[ 7:0]);
`UTILS_VAL1("Write DLR [ 7:0] =", testbench.i_wb_master_model.write_dat);
end
end
endtask // write_dlr
 
 
endmodule
/trunk/bench/verilog/wb_master_model.v
0,0 → 1,841
//////////////////////////////////////////////////////////////////////
//// ////
//// wb_master_model.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - mihad@opencores.org (Miha Dolenc) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`include "wb_model_defines.v"
`include "timescale.v"
 
module wb_master_model
(
wb_rst_i ,
wb_clk_i ,
wbm_cyc_o ,
wbm_cti_o ,
wbm_bte_o ,
wbm_stb_o ,
wbm_we_o ,
wbm_adr_o ,
wbm_sel_o ,
wbm_dat_o ,
wbm_dat_i ,
wbm_ack_i ,
wbm_err_i ,
wbm_rty_i
);
 
// set the parameters to impossible values, so errors will be detected at compile time
parameter wb_dat_width = 1 ;
parameter wb_adr_width = 1 ;
parameter wb_sel_width = 1 ;
 
real Tperiod ;
 
input wb_rst_i ,
wb_clk_i ;
 
output wbm_cyc_o ;
reg wbm_cyc_o ;
 
output [ 2: 0] wbm_cti_o ;
reg [ 2: 0] wbm_cti_o ;
 
output [ 1: 0] wbm_bte_o ;
reg [ 1: 0] wbm_bte_o ;
 
output wbm_stb_o ;
reg wbm_stb_o ;
 
output wbm_we_o ;
reg wbm_we_o ;
 
output [wb_adr_width - 1:0] wbm_adr_o ;
reg [wb_adr_width - 1:0] wbm_adr_o ;
 
output [wb_sel_width - 1:0] wbm_sel_o ;
reg [wb_sel_width - 1:0] wbm_sel_o ;
 
output [wb_dat_width - 1:0] wbm_dat_o ;
reg [wb_dat_width - 1:0] wbm_dat_o ;
 
input [wb_dat_width - 1:0] wbm_dat_i ;
 
input wbm_ack_i ;
 
input wbm_err_i ;
 
input wbm_rty_i ;
 
event write_transfer ;
event read_transfer ;
 
reg [wb_adr_width - 1:0] write_adr ;
reg [wb_sel_width - 1:0] write_sel ;
reg [wb_dat_width - 1:0] write_dat ;
 
reg [wb_adr_width - 1:0] read_adr ;
reg [wb_sel_width - 1:0] read_sel ;
reg [wb_dat_width - 1:0] read_dat ;
 
reg [wb_adr_width - 1:0] next_write_adr ;
reg [wb_sel_width - 1:0] next_write_sel ;
reg [wb_dat_width - 1:0] next_write_dat ;
reg [ 2: 0] next_write_cti ;
reg [ 1: 0] next_write_bte ;
 
event write_accepted ;
event write_request ;
 
reg [wb_adr_width - 1:0] next_read_adr ;
reg [wb_sel_width - 1:0] next_read_sel ;
reg [ 2: 0] next_read_cti ;
reg [ 1: 0] next_read_bte ;
 
event read_accepted ;
event read_request ;
 
real Tsetup ;
real Thold ;
 
initial Tsetup = 0.0 ;
initial Thold = 0.0 ;
 
reg reset_done ;
initial reset_done = 1'b0 ;
 
event error_event ;
reg [ 799: 0] error_message ;
 
initial
fork
begin
forever
begin
@(wb_rst_i) ;
if ((wb_rst_i ^ wb_rst_i) !== 1'b0)
begin
reset_done = 1'b0 ;
error_message = "Invalid WISHBONE reset line value detected" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
if (wb_rst_i === `WB_MODEL_RST_ACTIVE)
begin
reset_done = 1'b0 ;
end
end
end
begin
forever
begin
@(wb_rst_i) ;
if (wb_rst_i === `WB_MODEL_RST_ACTIVE)
begin
@(posedge wb_clk_i or wb_rst_i) ;
if (wb_rst_i !== `WB_MODEL_RST_ACTIVE)
begin
error_message = "Reset de-activated prior to at least one positive clock transition" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
else
begin
reset_done = 1'b1 ;
end
end
end
end
join
 
always@(wb_rst_i)
begin
if (wb_rst_i === `WB_MODEL_RST_ACTIVE)
wbm_cyc_o <= 1'b0 ;
end
 
reg access_in_progress ;
initial access_in_progress = 1'b0 ;
 
task start_write ;
input `WBM_MODEL_WRITE_IN_TYPE write_stim_i ;
output `WBM_MODEL_WRITE_OUT_TYPE write_res_o ;
reg [31: 0] num_of_slave_waits ;
reg end_access ;
begin:main
 
write_res_o = 'h0 ;
 
if (access_in_progress === 1'b1)
begin
error_message = "Task called when some other access was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
write_res_o`WBM_MODEL_WRITE_STIM_ERR = 1'b1 ;
disable main ;
end
 
if (reset_done !== 1'b1)
begin
error_message = "Task called before reset was applied to the design" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
write_res_o`WBM_MODEL_WRITE_STIM_ERR = 1'b1 ;
disable main ;
end
 
access_in_progress = 1'b1 ;
end_access = write_stim_i`WBM_MODEL_WRITE_LAST ;
 
if (write_stim_i`WBM_MODEL_WRITE_FAST_B2B !== 1'b1)
@(posedge wb_clk_i) ;
 
wbm_cyc_o <= #(Tperiod - Tsetup) 1'b1 ;
 
insert_waits(write_stim_i`WBM_MODEL_WRITE_WAITS, 'h0, num_of_slave_waits) ;
 
if ((num_of_slave_waits ^ num_of_slave_waits) === 'h0)
begin
error_message = "Slave responded to initial write access" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
num_of_slave_waits = 0 ;
wbm_stb_o <= #(Tperiod - Tsetup) 1'b1 ;
wbm_we_o <= #(Tperiod - Tsetup) 1'b1 ;
wbm_adr_o <= #(Tperiod - Tsetup) next_write_adr ;
wbm_dat_o <= #(Tperiod - Tsetup) get_write_dat(next_write_dat, next_write_sel) ;
wbm_sel_o <= #(Tperiod - Tsetup) next_write_sel ;
wbm_cti_o <= #(Tperiod - Tsetup) next_write_cti ;
wbm_bte_o <= #(Tperiod - Tsetup) next_write_bte ;
 
-> write_accepted ;
 
@(posedge wb_clk_i) ;
 
while((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0) & (num_of_slave_waits < write_stim_i`WBM_MODEL_WRITE_ALLOWED_SLAVE_WAITS))
begin
num_of_slave_waits = num_of_slave_waits + 1'b1 ;
write_adr = wbm_adr_o ;
write_sel = wbm_sel_o ;
write_dat = wbm_dat_o ;
-> write_request ;
@(posedge wb_clk_i) ;
end
 
if ((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0))
begin
error_message = "Cycle terminated because allowed number of slave wait states constraint violation" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
write_res_o`WBM_MODEL_WRITE_DESIGN_ERR = 1'b1 ;
end
else if ((wbm_ack_i + wbm_err_i + wbm_rty_i) !== 'h1)
begin
error_message = "Cycle terminated because invalid slave response was received" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
write_res_o`WBM_MODEL_WRITE_DESIGN_ERR = 1'b1 ;
end
else
begin
write_res_o`WBM_MODEL_WRITE_SLAVE_WAITS = num_of_slave_waits ;
write_res_o`WBM_MODEL_WRITE_SLAVE_ACK = wbm_ack_i ;
write_res_o`WBM_MODEL_WRITE_SLAVE_ERR = wbm_err_i ;
write_res_o`WBM_MODEL_WRITE_SLAVE_RTY = wbm_rty_i ;
 
if (wbm_ack_i === 1'b1)
begin
write_adr = wbm_adr_o ;
write_dat = wbm_dat_o ;
write_sel = wbm_sel_o ;
-> write_transfer ;
end
end
 
if (end_access)
begin
wbm_cyc_o <= #(Thold) 1'b0 ;
wbm_stb_o <= #(Thold) 1'bx ;
wbm_we_o <= #(Thold) 1'bx ;
wbm_sel_o <= #(Thold) 'hx ;
wbm_adr_o <= #(Thold) 'hx ;
wbm_dat_o <= #(Thold) 'hx ;
wbm_cti_o <= #(Thold) 'hx ;
wbm_bte_o <= #(Thold) 'hx ;
access_in_progress = 1'b0 ;
end
end
endtask // start_write
 
task subsequent_write ;
input `WBM_MODEL_WRITE_IN_TYPE write_stim_i ;
output `WBM_MODEL_WRITE_OUT_TYPE write_res_o ;
reg [31: 0] num_of_slave_waits ;
reg end_access ;
begin:main
 
write_res_o = 'h0 ;
 
if (access_in_progress !== 1'b1)
begin
error_message = "Task called when no access was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
write_res_o`WBM_MODEL_WRITE_STIM_ERR = 1'b1 ;
disable main ;
end
 
end_access = write_stim_i`WBM_MODEL_WRITE_LAST ;
 
insert_waits(write_stim_i`WBM_MODEL_WRITE_WAITS, 'h0, num_of_slave_waits) ;
 
if ((num_of_slave_waits ^ num_of_slave_waits) !== 'h0)
begin
num_of_slave_waits = write_stim_i`WBM_MODEL_WRITE_WAITS ;
end
wbm_stb_o <= #(Tperiod - Tsetup) 1'b1 ;
wbm_we_o <= #(Tperiod - Tsetup) 1'b1 ;
wbm_adr_o <= #(Tperiod - Tsetup) next_write_adr ;
wbm_dat_o <= #(Tperiod - Tsetup) get_write_dat(next_write_dat, next_write_sel) ;
wbm_sel_o <= #(Tperiod - Tsetup) next_write_sel ;
wbm_cti_o <= #(Tperiod - Tsetup) next_write_cti ;
wbm_bte_o <= #(Tperiod - Tsetup) next_write_bte ;
 
-> write_accepted ;
 
@(posedge wb_clk_i) ;
 
while((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0) & (num_of_slave_waits < write_stim_i`WBM_MODEL_WRITE_ALLOWED_SLAVE_WAITS))
begin
num_of_slave_waits = num_of_slave_waits + 1'b1 ;
write_adr = wbm_adr_o ;
write_sel = wbm_sel_o ;
write_dat = wbm_dat_o ;
-> write_request ;
@(posedge wb_clk_i) ;
end
 
if ((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0))
begin
error_message = "Cycle terminated because allowed number of slave wait states constraint violation" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
write_res_o`WBM_MODEL_WRITE_DESIGN_ERR = 1'b1 ;
end
else if ((wbm_ack_i + wbm_err_i + wbm_rty_i) !== 'h1)
begin
error_message = "Cycle terminated because invalid slave response was received" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
write_res_o`WBM_MODEL_WRITE_DESIGN_ERR = 1'b1 ;
end
else
begin
write_res_o`WBM_MODEL_WRITE_SLAVE_WAITS = num_of_slave_waits ;
write_res_o`WBM_MODEL_WRITE_SLAVE_ACK = wbm_ack_i ;
write_res_o`WBM_MODEL_WRITE_SLAVE_ERR = wbm_err_i ;
write_res_o`WBM_MODEL_WRITE_SLAVE_RTY = wbm_rty_i ;
 
if (wbm_ack_i === 1'b1)
begin
write_adr = wbm_adr_o ;
write_dat = wbm_dat_o ;
write_sel = wbm_sel_o ;
-> write_transfer ;
end
end
 
if (end_access)
begin
wbm_cyc_o <= #(Thold) 1'b0 ;
wbm_stb_o <= #(Thold) 1'bx ;
wbm_we_o <= #(Thold) 1'bx ;
wbm_sel_o <= #(Thold) 'hx ;
wbm_adr_o <= #(Thold) 'hx ;
wbm_dat_o <= #(Thold) 'hx ;
wbm_cti_o <= #(Thold) 'hx ;
wbm_bte_o <= #(Thold) 'hx ;
access_in_progress = 1'b0 ;
end
end
endtask // subsequent_write
 
task start_read ;
input `WBM_MODEL_READ_IN_TYPE read_stim_i ;
output `WBM_MODEL_READ_OUT_TYPE read_res_o ;
reg [31: 0] num_of_slave_waits ;
reg end_access ;
begin:main
 
read_res_o = 'h0 ;
 
if (access_in_progress === 1'b1)
begin
error_message = "Task called when some other access was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
read_res_o`WBM_MODEL_READ_STIM_ERR = 1'b1 ;
disable main ;
end
 
if (reset_done !== 1'b1)
begin
error_message = "Task called before reset was applied to the design" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
read_res_o`WBM_MODEL_READ_STIM_ERR = 1'b1 ;
disable main ;
end
 
access_in_progress = 1'b1 ;
end_access = read_stim_i`WBM_MODEL_READ_LAST ;
 
if (read_stim_i`WBM_MODEL_READ_FAST_B2B !== 1'b1)
@(posedge wb_clk_i) ;
 
wbm_cyc_o <= #(Tperiod - Tsetup) 1'b1 ;
 
insert_waits(read_stim_i`WBM_MODEL_READ_WAITS, 'h0, num_of_slave_waits) ;
 
if ((num_of_slave_waits ^ num_of_slave_waits) === 'h0)
begin
error_message = "Slave responded to initial read access" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
num_of_slave_waits = 0 ;
wbm_stb_o <= #(Tperiod - Tsetup) 1'b1 ;
wbm_we_o <= #(Tperiod - Tsetup) 1'b0 ;
wbm_adr_o <= #(Tperiod - Tsetup) next_read_adr ;
wbm_sel_o <= #(Tperiod - Tsetup) next_read_sel ;
wbm_cti_o <= #(Tperiod - Tsetup) next_read_cti ;
wbm_bte_o <= #(Tperiod - Tsetup) next_read_bte ;
 
-> read_accepted ;
 
@(posedge wb_clk_i) ;
 
while((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0) & (num_of_slave_waits < read_stim_i`WBM_MODEL_READ_ALLOWED_SLAVE_WAITS))
begin
num_of_slave_waits = num_of_slave_waits + 1'b1 ;
read_adr = wbm_adr_o ;
read_sel = wbm_sel_o ;
-> read_request ;
@(posedge wb_clk_i) ;
end
 
if ((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0))
begin
error_message = "Cycle terminated because allowed number of slave wait states constraint violation" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
read_res_o`WBM_MODEL_READ_DESIGN_ERR = 1'b1 ;
end
else if ((wbm_ack_i + wbm_err_i + wbm_rty_i) !== 'h1)
begin
error_message = "Cycle terminated because invalid slave response was received" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
read_res_o`WBM_MODEL_READ_DESIGN_ERR = 1'b1 ;
end
else
begin
read_res_o`WBM_MODEL_READ_SLAVE_WAITS = num_of_slave_waits ;
read_res_o`WBM_MODEL_READ_SLAVE_ACK = wbm_ack_i ;
read_res_o`WBM_MODEL_READ_SLAVE_ERR = wbm_err_i ;
read_res_o`WBM_MODEL_READ_SLAVE_RTY = wbm_rty_i ;
 
if (wbm_ack_i === 1'b1)
begin
read_adr = wbm_adr_o ;
read_dat = wbm_dat_i ;
read_sel = wbm_sel_o ;
-> read_transfer ;
end
end
 
if (end_access)
begin
wbm_cyc_o <= #(Thold) 1'b0 ;
wbm_stb_o <= #(Thold) 1'bx ;
wbm_we_o <= #(Thold) 1'bx ;
wbm_sel_o <= #(Thold) 'hx ;
wbm_adr_o <= #(Thold) 'hx ;
wbm_cti_o <= #(Thold) 'hx ;
wbm_bte_o <= #(Thold) 'hx ;
access_in_progress = 1'b0 ;
end
end
endtask // start_read
 
task subsequent_read ;
input `WBM_MODEL_READ_IN_TYPE read_stim_i ;
output `WBM_MODEL_READ_OUT_TYPE read_res_o ;
reg [31: 0] num_of_slave_waits ;
reg end_access ;
begin:main
 
read_res_o = 'h0 ;
 
if (access_in_progress !== 1'b1)
begin
error_message = "Task called when no access was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
read_res_o`WBM_MODEL_READ_STIM_ERR = 1'b1 ;
disable main ;
end
 
end_access = read_stim_i`WBM_MODEL_READ_LAST ;
 
insert_waits(read_stim_i`WBM_MODEL_READ_WAITS, 'h1, num_of_slave_waits) ;
 
if ((num_of_slave_waits ^ num_of_slave_waits) !== 'h0)
begin
num_of_slave_waits = read_stim_i`WBM_MODEL_READ_WAITS ;
end
wbm_stb_o <= #(Tperiod - Tsetup) 1'b1 ;
wbm_we_o <= #(Tperiod - Tsetup) 1'b0 ;
wbm_adr_o <= #(Tperiod - Tsetup) next_read_adr ;
wbm_sel_o <= #(Tperiod - Tsetup) next_read_sel ;
wbm_cti_o <= #(Tperiod - Tsetup) next_read_cti ;
wbm_bte_o <= #(Tperiod - Tsetup) next_read_bte ;
 
-> read_accepted ;
 
@(posedge wb_clk_i) ;
 
while((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0) & (num_of_slave_waits < read_stim_i`WBM_MODEL_READ_ALLOWED_SLAVE_WAITS))
begin
num_of_slave_waits = num_of_slave_waits + 1'b1 ;
read_adr = wbm_adr_o ;
read_sel = wbm_sel_o ;
-> read_request ;
@(posedge wb_clk_i) ;
end
 
if ((wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0))
begin
error_message = "Cycle terminated because allowed number of slave wait states constraint violation" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
read_res_o`WBM_MODEL_READ_DESIGN_ERR = 1'b1 ;
end
else if ((wbm_ack_i + wbm_err_i + wbm_rty_i) !== 'h1)
begin
error_message = "Cycle terminated because invalid slave response was received" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end_access = 1'b1 ;
read_res_o`WBM_MODEL_WRITE_DESIGN_ERR = 1'b1 ;
end
else
begin
read_res_o`WBM_MODEL_READ_SLAVE_WAITS = num_of_slave_waits ;
read_res_o`WBM_MODEL_READ_SLAVE_ACK = wbm_ack_i ;
read_res_o`WBM_MODEL_READ_SLAVE_ERR = wbm_err_i ;
read_res_o`WBM_MODEL_READ_SLAVE_RTY = wbm_rty_i ;
 
if (wbm_ack_i === 1'b1)
begin
read_adr = wbm_adr_o ;
read_dat = wbm_dat_i ;
read_sel = wbm_sel_o ;
-> read_transfer ;
end
end
 
if (end_access)
begin
wbm_cyc_o <= #(Thold) 1'b0 ;
wbm_stb_o <= #(Thold) 1'bx ;
wbm_we_o <= #(Thold) 1'bx ;
wbm_sel_o <= #(Thold) 'hx ;
wbm_adr_o <= #(Thold) 'hx ;
wbm_cti_o <= #(Thold) 'hx ;
wbm_bte_o <= #(Thold) 'hx ;
access_in_progress = 1'b0 ;
end
end
endtask // subsequent_read
 
task insert_waits ;
input [31: 0] num_of_waits_i ;
input read_req_on_wait_i ;
output [31: 0] num_of_slave_waits ;
reg [31: 0] cur_num_of_waits ;
begin
num_of_slave_waits = 'hx ;
 
for (cur_num_of_waits = 0 ; cur_num_of_waits < num_of_waits_i ; cur_num_of_waits = cur_num_of_waits + 1'b1)
begin
wbm_stb_o <= #(Thold) 1'b0 ;
wbm_adr_o <= #(Thold) 'hx ;
wbm_sel_o <= #(Thold) 'hx ;
wbm_we_o <= #(Thold) 'hx ;
wbm_dat_o <= #(Thold) 'hx ;
wbm_cti_o <= #(Thold) 'hx ;
wbm_bte_o <= #(Thold) 'hx ;
@(posedge wb_clk_i) ;
 
if (read_req_on_wait_i)
begin
if ( (wbm_ack_i === 1'b0) & (wbm_err_i === 1'b0) & (wbm_rty_i === 1'b0) )
begin
if ( (next_read_cti === 'h1) | (next_read_cti === 'h2) | (next_read_cti === 'h7) )
begin
read_adr = next_read_adr ;
read_sel = next_read_sel ;
-> read_request ;
end
end
end
 
if ((num_of_slave_waits ^ num_of_slave_waits) !== 'h0)
begin
if ((wbm_ack_i !== 1'b0) | (wbm_err_i !== 1'b0) | (wbm_rty_i !== 1'b0))
num_of_slave_waits = cur_num_of_waits ;
end
end
end
endtask
 
always@(posedge wb_clk_i)
begin:wb_monitoring_blk
reg burst_in_progress ;
reg ack_prev ;
reg rty_prev ;
reg err_prev ;
reg stb_prev ;
reg cyc_prev ;
reg [wb_dat_width - 1:0] sdat_prev ;
 
ack_prev <= wbm_ack_i ;
rty_prev <= wbm_rty_i ;
err_prev <= wbm_err_i ;
stb_prev <= wbm_stb_o ;
cyc_prev <= wbm_cyc_o ;
sdat_prev <= wbm_dat_i ;
 
if (wb_rst_i === `WB_MODEL_RST_ACTIVE)
begin
if (wbm_ack_i !== 1'b0)
begin
error_message = "ACK input signal was not de-asserted while reset was asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
if (wbm_err_i !== 1'b0)
begin
error_message = "ERR input signal was not de-asserted while reset was asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
if (wbm_rty_i !== 1'b0)
begin
error_message = "RTY input signal was not de-asserted while reset was asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
burst_in_progress <= 1'b0 ;
end
else
begin
if (wbm_cyc_o !== 1'b1)
begin
if (wbm_ack_i !== 1'b0)
begin
error_message = "ACK input signal was asserted while no cycle was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
if (wbm_err_i !== 1'b0)
begin
error_message = "ERR input signal was asserted while no cycle was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
if (wbm_rty_i !== 1'b0)
begin
error_message = "RTY input signal was asserted while no cycle was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
end
else
begin
if (burst_in_progress !== 1'b1)
begin
if ((wbm_ack_i !== 1'b0) & (wbm_stb_o !== 1'b1))
begin
error_message = "ACK input signal was asserted while STB was de-asserted and no burst was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
if ((wbm_err_i !== 1'b0) & (wbm_stb_o !== 1'b1))
begin
error_message = "ERR input signal was asserted while STB was de-asserted and no burst was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
if ((wbm_rty_i !== 1'b0) & (wbm_stb_o !== 1'b1))
begin
error_message = "RTY input signal was asserted while STB was de-asserted and no burst was in progress" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
end
else
begin
if ((ack_prev !== 1'b0) & (stb_prev !== 1'b1))
begin
if (wbm_ack_i !== 1'b1)
begin
error_message = "Slave de-asserted ACK signal during burst cycle without receiving STB asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
if (wbm_we_o !== 'b1)
begin
if (sdat_prev !== wbm_dat_i)
begin
error_message = "Slave changed the value of data output bus during burst cycle without receiving STB asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
end
end
 
if ((rty_prev !== 1'b0) & (stb_prev !== 1'b1) & (wbm_rty_i !== 1'b1))
begin
error_message = "Slave de-asserted RTY signal during burst cycle without receiving STB asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
 
if ((err_prev !== 1'b0) & (stb_prev !== 1'b1) & (wbm_err_i !== 1'b1))
begin
error_message = "Slave de-asserted ERR signal during burst cycle without receiving STB asserted" ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
end
 
if (wbm_stb_o === 1'b1)
begin
case (wbm_cti_o)
3'b000:burst_in_progress <= 1'b0 ;
3'b001:burst_in_progress <= 1'b1 ;
3'b010:burst_in_progress <= 1'b1 ;
3'b011:burst_in_progress <= 1'b0 ;
3'b100:burst_in_progress <= 1'b0 ;
3'b101:burst_in_progress <= 1'b0 ;
3'b110:burst_in_progress <= 1'b0 ;
3'b111:if (wbm_ack_i === 1'b1) burst_in_progress <= 1'b0 ;
default:
begin
error_message = "WISHBONE master sent invalid cycle type identifier" ;
burst_in_progress <= 1'bx ;
`WB_MODEL_ERR_MSG(error_message) ;
-> error_event ;
end
endcase
 
if (wbm_err_i === 1'b1)
burst_in_progress <= 1'b0 ;
 
if (wbm_rty_i === 1'b1)
burst_in_progress <= 1'b0 ;
 
end
end
end
end
 
function [wb_dat_width - 1:0] get_write_dat ;
input [wb_dat_width - 1:0] dat_i ;
input [wb_sel_width - 1:0] sel_i ;
 
integer cur_bit ;
reg [wb_dat_width - 1:0] dat_o ;
begin
for (cur_bit = 0 ; cur_bit < wb_dat_width ; cur_bit = cur_bit + 1'b1)
begin
if (sel_i[cur_bit >> 3] === 1'b1)
dat_o[cur_bit] = dat_i[cur_bit] ;
else
dat_o[cur_bit] = 1'bx ;
end
 
get_write_dat = dat_o ;
end
endfunction // get_write_dat
 
endmodule
 
/trunk/bench/verilog/uart_device_utilities.v
0,0 → 1,320
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_device_utilities.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - tadej@opencores.org (Tadej Markovic) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`include "uart_defines.v"
`include "uart_testbench_defines.v"
`include "wb_model_defines.v"
`include "timescale.v"
 
module uart_device_utilities;
 
// UART receiver setting TASKs
//############################
 
// Set RX length
task set_rx_length;
input [3:0] len;
begin
`UTILS_MSG("SETTING RX CHAR length.");
testbench.i_uart_device.rx_length = len;
`UTILS_VAL1("Length:", len);
end
endtask // set_rx_length
 
// Enable RX odd parity
task enable_rx_odd_parity;
begin
`UTILS_MSG("ENABLING RX CHAR odd parity.");
testbench.i_uart_device.rx_odd_parity = 1'b1;
testbench.i_uart_device.rx_even_parity = 1'b0;
testbench.i_uart_device.rx_stick1_parity = 1'b0;
testbench.i_uart_device.rx_stick0_parity = 1'b0;
testbench.i_uart_device.rx_parity_enabled = 1'b1;
end
endtask // enable_rx_odd_parity
 
// Enable RX even parity
task enable_rx_even_parity;
begin
`UTILS_MSG("ENABLING RX CHAR even parity.");
testbench.i_uart_device.rx_odd_parity = 1'b0;
testbench.i_uart_device.rx_even_parity = 1'b1;
testbench.i_uart_device.rx_stick1_parity = 1'b0;
testbench.i_uart_device.rx_stick0_parity = 1'b0;
testbench.i_uart_device.rx_parity_enabled = 1'b1;
end
endtask // enable_rx_even_parity
 
// Enable RX stick1 parity
task enable_rx_stick1_parity;
begin
`UTILS_MSG("ENABLING RX CHAR stick1 parity.");
testbench.i_uart_device.rx_odd_parity = 1'b0;
testbench.i_uart_device.rx_even_parity = 1'b0;
testbench.i_uart_device.rx_stick1_parity = 1'b1;
testbench.i_uart_device.rx_stick0_parity = 1'b0;
testbench.i_uart_device.rx_parity_enabled = 1'b1;
end
endtask // enable_rx_stick1_parity
 
// Enable RX stick0 parity
task enable_rx_stick0_parity;
begin
`UTILS_MSG("ENABLING RX CHAR stick0 parity.");
testbench.i_uart_device.rx_odd_parity = 1'b0;
testbench.i_uart_device.rx_even_parity = 1'b0;
testbench.i_uart_device.rx_stick1_parity = 1'b0;
testbench.i_uart_device.rx_stick0_parity = 1'b1;
testbench.i_uart_device.rx_parity_enabled = 1'b1;
end
endtask // enable_rx_stick0_parity
 
// Disable RX parity
task disable_rx_parity;
begin
`UTILS_MSG("DISABLING RX CHAR parity.");
testbench.i_uart_device.rx_odd_parity = 1'b0;
testbench.i_uart_device.rx_even_parity = 1'b0;
testbench.i_uart_device.rx_stick1_parity = 1'b0;
testbench.i_uart_device.rx_stick0_parity = 1'b0;
testbench.i_uart_device.rx_parity_enabled = 1'b0;
end
endtask // disable_rx_parity
 
// Set 1 or 2 (1.5) RX stop bits
task set_rx_second_stop_bit;
input second_stop_bit;
begin
if (~second_stop_bit)
begin
`UTILS_MSG("SETTING RX CHAR 1 stop bit.");
end
else if (second_stop_bit && (testbench.i_uart_device.rx_length == 5))
begin
`UTILS_MSG("SETTING RX CHAR 1.5 stop bit.");
end
else
begin
`UTILS_MSG("SETTING RX CHAR 2 stop bits.");
end
testbench.i_uart_device.rx_stop_bit_1 = ~second_stop_bit;
testbench.i_uart_device.rx_stop_bit_1_5 = second_stop_bit & (testbench.i_uart_device.rx_length == 5);
testbench.i_uart_device.rx_stop_bit_2 = second_stop_bit & (testbench.i_uart_device.rx_length != 5);
end
endtask // set_rx_second_stop_bit
 
// UART transmitter setting TASKs
//###############################
 
// Set TX length
task set_tx_length;
input [3:0] len;
begin
`UTILS_MSG("SETTING TX CHAR length.");
testbench.i_uart_device.tx_length = len;
`UTILS_VAL1("Length:", len);
end
endtask // set_tx_length
 
// Enable TX odd parity
task enable_tx_odd_parity;
begin
`UTILS_MSG("ENABLING TX CHAR odd parity.");
testbench.i_uart_device.tx_odd_parity = 1'b1;
testbench.i_uart_device.tx_even_parity = 1'b0;
testbench.i_uart_device.tx_stick1_parity = 1'b0;
testbench.i_uart_device.tx_stick0_parity = 1'b0;
testbench.i_uart_device.tx_parity_enabled = 1'b1;
end
endtask // enable_tx_odd_parity
 
// Enable TX even parity
task enable_tx_even_parity;
begin
`UTILS_MSG("ENABLING TX CHAR even parity.");
testbench.i_uart_device.tx_odd_parity = 1'b0;
testbench.i_uart_device.tx_even_parity = 1'b1;
testbench.i_uart_device.tx_stick1_parity = 1'b0;
testbench.i_uart_device.tx_stick0_parity = 1'b0;
testbench.i_uart_device.tx_parity_enabled = 1'b1;
end
endtask // enable_tx_even_parity
 
// Enable TX stick1 parity
task enable_tx_stick1_parity;
begin
`UTILS_MSG("ENABLING TX CHAR stick1 parity.");
testbench.i_uart_device.tx_odd_parity = 1'b0;
testbench.i_uart_device.tx_even_parity = 1'b0;
testbench.i_uart_device.tx_stick1_parity = 1'b1;
testbench.i_uart_device.tx_stick0_parity = 1'b0;
testbench.i_uart_device.tx_parity_enabled = 1'b1;
end
endtask // enable_tx_stick1_parity
 
// Enable TX stick0 parity
task enable_tx_stick0_parity;
begin
`UTILS_MSG("ENABLING TX CHAR stick0 parity.");
testbench.i_uart_device.tx_odd_parity = 1'b0;
testbench.i_uart_device.tx_even_parity = 1'b0;
testbench.i_uart_device.tx_stick1_parity = 1'b0;
testbench.i_uart_device.tx_stick0_parity = 1'b1;
testbench.i_uart_device.tx_parity_enabled = 1'b1;
end
endtask // enable_tx_stick0_parity
 
// Disable TX parity
task disable_tx_parity;
begin
`UTILS_MSG("DISABLING TX CHAR parity.");
testbench.i_uart_device.tx_odd_parity = 1'b0;
testbench.i_uart_device.tx_even_parity = 1'b0;
testbench.i_uart_device.tx_stick1_parity = 1'b0;
testbench.i_uart_device.tx_stick0_parity = 1'b0;
testbench.i_uart_device.tx_parity_enabled = 1'b0;
end
endtask // disable_tx_parity
// Correct TX parity
task correct_tx_parity;
begin
`UTILS_MSG("DISABLING WRONG parity generation.");
testbench.i_uart_device.tx_parity_wrong = 1'b0;
end
endtask // correct_tx_parity
// Wrong TX parity
task wrong_tx_parity;
begin
`UTILS_MSG("ENABLING WRONG parity generation.");
testbench.i_uart_device.tx_parity_wrong = 1'b1;
end
endtask // wrong_tx_parity
 
// Correct TX frame
task correct_tx_frame;
begin
`UTILS_MSG("DISABLING WRONG frame generation.");
testbench.i_uart_device.tx_framing_wrong = 1'b0;
end
endtask // correct_tx_frame
 
// Wrong TX frame
task wrong_tx_frame;
begin
`UTILS_MSG("ENABLING WRONG frame generation.");
testbench.i_uart_device.tx_framing_wrong = 1'b1;
end
endtask // wrong_tx_frame
 
// Generate TX glitch
task generate_tx_glitch;
input [23:0] generate_glitch_num;
begin
if (generate_glitch_num == 0)
begin
`UTILS_MSG("DISABLING 1 TIME glitch generation with CLKs delay.");
end
else
begin
`UTILS_MSG("ENABLING 1 TIME glitch generation with CLKs delay.");
end
testbench.i_uart_device.tx_glitch_num = generate_glitch_num;
`UTILS_VAL1("CLKs delay from start bit edge:", generate_glitch_num);
end
endtask // generate_tx_glitch
 
// Enable TX break
task enable_tx_break;
input [15:0] break_num;
begin
`UTILS_MSG("ENABLING brake generation with each TX CHAR with brake length.");
testbench.i_uart_device.tx_break_enable = 1'b1;
testbench.i_uart_device.tx_break_num = break_num;
`UTILS_VAL1("Brake bit length:", break_num);
end
endtask // enable_tx_break
// Disable TX break
task disable_tx_break;
begin
`UTILS_MSG("DISABLING brake generation with each TX CHAR.");
testbench.i_uart_device.tx_break_enable = 1'b0;
end
endtask // disable_tx_break
 
// UART transmitter send TASKs
//############################
 
// Send character
task send_char;
input [7:0] char;
begin
testbench.i_uart_device.send_packet(1'b0, char, 1);
end
endtask // Send character
// Send random character
task send_rnd_char;
begin
testbench.i_uart_device.send_packet(1'b1, 8'h0, 1);
end
endtask // send_rnd_char
// Send burst random character
task send_burst_rnd_char;
input [31:0] num_of_char;
integer i;
begin
testbench.i_uart_device.send_packet(1'b1, 8'h0, num_of_char);
end
endtask // send_burst_rnd_char
 
 
endmodule
/trunk/bench/verilog/uart_testbench_utilities.v
0,0 → 1,320
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_testbench_utilities.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - tadej@opencores.org (Tadej Markovic) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`include "uart_defines.v"
`include "uart_testbench_defines.v"
`include "wb_model_defines.v"
`include "timescale.v"
 
module testbench_utilities;
 
// Basic system TASKs
//###################
 
// DO_RESET
task do_reset;
begin
testbench.wb_reset = 1'b1;
#1;
`UTILS_MSG("RESET signal asynchronously set.");
end
endtask // do_reset
 
// RELEASE_RESET
task release_reset;
begin
@(posedge testbench.wb_clk);
#1;
testbench.wb_reset = 1'b0;
`UTILS_MSG("RESET signal released synchronously to WB clk.");
end
endtask // release_reset
 
// DISABLE_CLK_GENERATORS
task disable_clk_generators;
input wb_clk_disable;
input rx_clk_disable;
input tx_clk_disable;
input tx_clk_divided_disable;
begin
`UTILS_MSG("Following clocks are DISABLED:");
if (wb_clk_disable)
begin
testbench.wb_clk_en = 1'b0;
`UTILS_MSG("- WB_clk");
end
if (rx_clk_disable)
begin
testbench.i_uart_device.rx_clk_en = 1'b0;
`UTILS_MSG("- RX_clk");
end
if (tx_clk_disable)
begin
testbench.i_uart_device.tx_clk_en = 1'b0;
`UTILS_MSG("- TX_clk");
end
if (tx_clk_divided_disable)
begin
testbench.i_uart_device.tx_clk_divided_en = 1'b0;
`UTILS_MSG("- TX_clk_divided");
end
if (~wb_clk_disable && ~rx_clk_disable && ~tx_clk_disable && ~tx_clk_divided_disable)
begin
`UTILS_MSG("- NO clocks DISABLED");
end
end
endtask // disable_clk_generators
 
// ENABLE_CLK_GENERATORS
task enable_clk_generators;
input wb_clk_enable;
input rx_clk_enable;
input tx_clk_enable;
input tx_clk_divided_enable;
begin
`UTILS_MSG("Following clocks are ENABLED:");
if (wb_clk_enable)
begin
testbench.wb_clk_en = 1'b1;
`UTILS_MSG("- WB_clk");
end
if (rx_clk_enable)
begin
testbench.i_uart_device.rx_clk_en = 1'b1;
`UTILS_MSG("- RX_clk");
end
if (tx_clk_enable)
begin
testbench.i_uart_device.tx_clk_en = 1'b1;
`UTILS_MSG("- TX_clk");
end
if (tx_clk_divided_enable)
begin
testbench.i_uart_device.tx_clk_divided_en = 1'b1;
`UTILS_MSG("- TX_clk_divided");
end
if (~wb_clk_enable && ~rx_clk_enable && ~tx_clk_enable && ~tx_clk_divided_enable)
begin
`UTILS_MSG("- NO clocks ENABLED");
end
end
endtask // enable_clk_generators
 
// SET_DEVICE_TX_RX_CLK_PERIOD
task set_device_tx_rx_clk_period;
input [31:0] clk_period;
begin
testbench.i_uart_device.T_clk_period = clk_period;
`UTILS_VAL1("UART DEVICE TX/RX clock period:", clk_period);
end
endtask // set_device_tx_rx_clk_period
 
// SET_DEVICE_TX_CLK_DELAY
task set_device_tx_clk_delay;
input [31:0] tx_clk_delay;
begin
testbench.i_uart_device.T_clk_delay = tx_clk_delay;
`UTILS_VAL1("UART DEVICE TX clock delay:", tx_clk_delay);
end
endtask // set_device_tx_clk_delay
 
// SET_DEVICE_TX_RX_CLK_DIVISOR
task set_device_tx_rx_clk_divisor;
input [31:0] clk_divisor;
begin
testbench.i_uart_device.T_divisor = clk_divisor;
`UTILS_VAL1("UART DEVICE TX/RX clock divisor:", clk_divisor);
end
endtask // set_device_tx_rx_clk_divisor
 
// SET_WB_CLK_PERIOD
task set_wb_clock_period;
input [31:0] clk_period;
begin
testbench.T_wb_clk_period = clk_period;
testbench.i_uart_device.T_clk_period = clk_period;
`UTILS_VAL1("WB & UART DEVICE TX/RX clock period:", clk_period);
end
endtask // set_wb_clock_period
 
// WB_CLK_FOLLOWS_DEVICE_RX_CLK
task wb_clk_follows_device_rx_clk;
input [31:0] time_delay_i;
integer time_delay;
begin
time_delay = time_delay_i;
@(posedge testbench.wb_clk);
testbench.wb_clk_en = 1'b0;
@(posedge testbench.i_uart_device.rx_clk);
#time_delay testbench.wb_clk = 1'b1;
testbench.wb_clk_en = 1'b1;
`UTILS_VAL1("WB followed UART DEVICE rising edge RX clock for time delay:", time_delay);
end
endtask // wb_clk_follows_device_rx_clk
 
// DEVICE_RX_CLK_FOLLOWS_WB_CLK
task device_rx_clk_follows_wb_clk;
input [31:0] time_delay_i;
integer time_delay;
begin
time_delay = time_delay_i;
@(posedge testbench.i_uart_device.rx_clk);
testbench.i_uart_device.rx_clk_en = 1'b0;
@(posedge testbench.wb_clk);
#time_delay testbench.i_uart_device.rx_clk = 1'b1;
testbench.i_uart_device.rx_clk_en = 1'b1;
`UTILS_VAL1("UART DEVICE RX followed WB rising edge clock for time delay:", time_delay);
end
endtask // device_rx_clk_follows_wb_clk
// Utility tasks
//##############
 
// WAIT_FOR_NUM_OF_WB_CLK
task wait_for_num_of_wb_clk;
input [31:0] num_of_clk;
integer count;
begin
count = 0;
`UTILS_VAL1("Waiting for following number of WB CLK periods:", num_of_clk);
while (count < num_of_clk)
begin
@(testbench.wb_clk);
count = count + 1'b1;
#1;
end
`UTILS_MSG("Waiting expired.");
end
endtask // wait_for_num_of_wb_clk
 
// WAIT_RX_FIFO_FULL_REGARDLESS_INT
task wait_rx_fifo_full_regardless_int;
integer count;
begin
count = 0;
`UTILS_MSG("Waiting for RX FIFO to get full regardless of interrupt.");
fork
begin:fifo_full_loop
while (testbench.i_uart_top.regs.receiver.fifo_rx.count <
testbench.i_uart_top.regs.receiver.fifo_rx.fifo_depth) // While RX fifo not full
begin
@(testbench.wb_clk);
end
disable counter;
`UTILS_MSG("RX FIFO got full.");
end
begin:counter
while (count < testbench.max_wait_cnt)
begin
@(testbench.wb_clk);
count = count + 1'b1;
#1;
end
disable fifo_full_loop;
`UTILS_ERROR("WAIT counter exceeded max value.");
end
join
end
endtask // wait_rx_fifo_full_regardless_int
 
// WAIT_RX_FIFO_FULL_UNLESS_INT
task wait_rx_fifo_full_unless_int;
integer count;
begin
count = 0;
`UTILS_MSG("Waiting for RX FIFO to get full unless interrupt occures before.");
fork
begin:fifo_full_loop
while (testbench.i_uart_top.regs.receiver.fifo_rx.count <
testbench.i_uart_top.regs.receiver.fifo_rx.fifo_depth) // While RX fifo not full
begin
@(testbench.wb_clk);
end
disable counter;
disable int_loop;
`UTILS_MSG("RX FIFO got full.");
end
begin:int_loop
if (testbench.ier_reg[3:0] == 4'h0)
begin
`UTILS_MSG("All interrupts are disabled.");
end
else
begin
`UTILS_MSG("Interrupts are enabled in IE Register.");
`UTILS_VAL1("IER:", testbench.ier_reg);
@(testbench.int_aserted);
`UTILS_MSG("Interrupt is asserted. The pending interrupt of highest priority is in II Register.");
`UTILS_VAL1("IIR:", testbench.iir_reg);
disable counter;
disable fifo_full_loop;
end
end
begin:counter
while (count < testbench.max_wait_cnt)
begin
@(testbench.wb_clk);
count = count + 1'b1;
#1;
end
disable int_loop;
disable fifo_full_loop;
`UTILS_ERROR("WAIT counter exceeded max value.");
end
join
end
endtask // wait_rx_fifo_full_unless_int
 
 
// UART Initialize TASKs
//######################
 
// POSSIBLE INITIALIZE TASKS - NOW FEW STEPS ARE MADE IN EACH testcase!!!
 
 
endmodule
/trunk/bench/verilog/wb_model_defines.v
0,0 → 1,79
//////////////////////////////////////////////////////////////////////
//// ////
//// wb_model_defines.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - mihad@opencores.org (Miha Dolenc) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`define WB_MODEL_RST_ACTIVE 1'b1
`define WB_MODEL_ERR_MSG(TEXT) $display("Error detected at time %t!", $time) ; $display("%m reports: %0s.", TEXT) ; testcase.msg = TEXT ; -> testcase.err_event
 
`define WBM_MODEL_WRITE_IN_TYPE [65: 0]
`define WBM_MODEL_WRITE_WAITS [31: 0]
`define WBM_MODEL_WRITE_ALLOWED_SLAVE_WAITS [63:32]
`define WBM_MODEL_WRITE_LAST [64:64]
`define WBM_MODEL_WRITE_FAST_B2B [65:65]
 
`define WBM_MODEL_WRITE_OUT_TYPE [36: 0]
`define WBM_MODEL_WRITE_SLAVE_WAITS [31: 0]
`define WBM_MODEL_WRITE_STIM_ERR [32:32]
`define WBM_MODEL_WRITE_DESIGN_ERR [33:33]
`define WBM_MODEL_WRITE_SLAVE_ACK [34:34]
`define WBM_MODEL_WRITE_SLAVE_ERR [35:35]
`define WBM_MODEL_WRITE_SLAVE_RTY [36:36]
 
`define WBM_MODEL_READ_IN_TYPE [65: 0]
`define WBM_MODEL_READ_WAITS [31: 0]
`define WBM_MODEL_READ_ALLOWED_SLAVE_WAITS [63:32]
`define WBM_MODEL_READ_LAST [64:64]
`define WBM_MODEL_READ_FAST_B2B [65:65]
 
`define WBM_MODEL_READ_OUT_TYPE [36: 0]
`define WBM_MODEL_READ_SLAVE_WAITS [31: 0]
`define WBM_MODEL_READ_STIM_ERR [32:32]
`define WBM_MODEL_READ_DESIGN_ERR [33:33]
`define WBM_MODEL_READ_SLAVE_ACK [34:34]
`define WBM_MODEL_READ_SLAVE_ERR [35:35]
`define WBM_MODEL_READ_SLAVE_RTY [36:36]
 
/trunk/bench/verilog/uart_testbench_defines.v
0,0 → 1,86
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_testbench_defines.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - tadej@opencores.org (Tadej Markovic) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`ifdef VERBOSE
// Displaying messages to CRT and providing to "testcase"
`define SEVERE_ERROR(TEXT) $display("Time: %t (%m)", $time); $display("*E, Object %m reporting severe error:"); $display(" %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.severe_err_msg = TEXT; -> testcase.severe_err_event; @(testcase.testbench_log_written)
`define UTILS_WARNING(TEXT) $display("Time: %t (%m)", $time); $display("*W, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.wrn_event; @(testcase.testbench_log_written)
`define UTILS_ERROR(TEXT) $display("Time: %t (%m)", $time); $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
`define BENCH_WARNING(TEXT) $display("Time: %t (%m)", $time); $display("*W, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.wrn_event; @(testcase.testbench_log_written)
`define BENCH_ERROR(TEXT) $display("Time: %t (%m)", $time); $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
`define TC_ERROR(TEXT) $display("Time: %t (%m)", $time); $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
`define DEVICE_WARNING(TEXT) $display("Time: %t (%m)", $time); $display("*W, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.wrn_event; @(testcase.testbench_log_written)
`define DEVICE_ERROR(TEXT) $display("Time: %t (%m)", $time); $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
// Displaying messages to CRT
`define UTILS_MSG(TEXT) $display("Time %t (%m)", $time); $display("*N, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.msg_event; @(testcase.testbench_log_written)
`define UTILS_VAL1(TEXT, VAL) $display("Time %t (%m)", $time); $display("*N, %0s %0h.", TEXT, VAL); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; testcase.val = VAL; -> testcase.val_event; @(testcase.testbench_log_written)
`define BENCH_MSG(TEXT) $display("Time %t (%m)", $time); $display("*N, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.msg_event; @(testcase.testbench_log_written)
`define BENCH_VAL1(TEXT, VAL) $display("Time %t (%m)", $time); $display("*N, %0s %0h.", TEXT, VAL); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; testcase.val = VAL; -> testcase.val_event; @(testcase.testbench_log_written)
`define TC_MSG(TEXT) $display("Time %t (%m)", $time); $display("*N, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.msg_event; @(testcase.testbench_log_written)
`define TC_VAL1(TEXT, VAL) $display("Time %t (%m)", $time); $display("*N, %0s %0h.", TEXT, VAL); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; testcase.val = VAL; -> testcase.val_event; @(testcase.testbench_log_written)
`else
// Displaying messages to CRT and providing to "testcase"
`define SEVERE_ERROR(TEXT) $display("*E, Object %m reporting severe error:"); $display(" %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.severe_err_msg = TEXT; -> testcase.severe_err_event; @(testcase.testbench_log_written)
`define UTILS_WARNING(TEXT) $display("*W, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.wrn_event; @(testcase.testbench_log_written)
`define UTILS_ERROR(TEXT) $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
`define BENCH_WARNING(TEXT) $display("*W, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.wrn_event; @(testcase.testbench_log_written)
`define BENCH_ERROR(TEXT) $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
`define TC_ERROR(TEXT) $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
`define DEVICE_WARNING(TEXT) $display("*W, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.wrn_event; @(testcase.testbench_log_written)
`define DEVICE_ERROR(TEXT) $display("*E, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.err_event; @(testcase.testbench_log_written)
// Displaying messages to CRT
`define UTILS_MSG(TEXT) $display("*N, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.msg_event; @(testcase.testbench_log_written)
`define UTILS_VAL1(TEXT, VAL) $display("*N, %0s %0h.", TEXT, VAL); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; testcase.val = VAL; -> testcase.val_event; @(testcase.testbench_log_written)
`define BENCH_MSG(TEXT) $display("*N, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.msg_event; @(testcase.testbench_log_written)
`define BENCH_VAL1(TEXT, VAL) $display("*N, %0s %0h.", TEXT, VAL); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; testcase.val = VAL; -> testcase.val_event; @(testcase.testbench_log_written)
`define TC_MSG(TEXT) $display("*N, %0s", TEXT); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; -> testcase.msg_event; @(testcase.testbench_log_written)
`define TC_VAL1(TEXT, VAL) $display("*N, %0s %0h.", TEXT, VAL); $sformat(testcase.tim, "Time: %t (%m)", $time); testcase.msg = TEXT; testcase.val = VAL; -> testcase.val_event; @(testcase.testbench_log_written)
`endif
 
// Testcase end
`define PROMPT #1000000; log.end_log; $finish
/trunk/bench/verilog/uart_test.v Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/trunk/bench/verilog/uart_device.v
0,0 → 1,714
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_device.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - tadej@opencores.org (Tadej Markovic) ////
//// - igorm@opencores.org (Igor Mohor) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`include "uart_testbench_defines.v"
`include "timescale.v"
 
module uart_device
(
// UART signals
stx_i,
srx_o,
// Modem signals
rts_i,
cts_o,
dtr_i,
dsr_o,
ri_o,
dcd_o
);
 
 
// IN/OUT signals
//###############
 
// UART signals
input stx_i;
output srx_o;
// Modem signals
input rts_i;
output cts_o;
input dtr_i;
output dsr_o;
output ri_o;
output dcd_o;
 
 
// INTERNAL signals
//#################
 
 
// Clock generation signals
//#########################
 
// Operational and transmission clock signals
reg rx_clk; // RX device clock with period T_clk_period (should be equal to wb_clk_period)
reg tx_clk; // TX device clock with period (T_clk_period + T_clk_delay)
reg tx_clk_divided; // divided TX device clock with period ((T_clk_period + T_clk_delay) * T_divisor * 16)
// Clock enable signals
reg rx_clk_en = 1'b1;
reg tx_clk_en = 1'b1;
reg tx_clk_divided_en = 1'b1;
// Clock period variables
real T_clk_period = 20;
real T_clk_delay = 0;
integer T_divisor = 5;
 
 
// IN/OUT assignment signals
//##########################
 
// Modem signals
wire rts;
wire dtr;
 
 
// UART receiver signals
//######################
 
// RX packet control signals
wire rx;
reg [3:0] rx_length;
reg rx_odd_parity;
reg rx_even_parity;
reg rx_stick1_parity;
reg rx_stick0_parity;
reg rx_parity_enabled;
reg rx_stop_bit_1;
reg rx_stop_bit_1_5;
reg rx_stop_bit_2;
// RX logic signals
wire [3:0] rx_total_length;
wire [5:0] rx_break_detection_length;
reg rx_packet_end;
reg rx_packet_end_q;
reg rx_clk_cnt_en;
reg [31:0] rx_clk_cnt;
reg rx_sample_clock;
integer rx_bit_index;
integer rx_stop_bit_index;
reg [7:0] rx_data;
reg [1:0] rx_stop;
reg rx_framing_error;
reg rx_parity;
reg rx_parity_error;
reg rx_break_detected;
reg rx_break_detected_q;
reg [31:0] rx_break_cnt;
// RX events
event device_received_packet;
event device_received_last_bit;
event device_received_stop_bit;
event device_detected_rx_break;
 
 
// UART transmitter signals
//#########################
 
// TX packet control signals
reg tx;
reg [3:0] tx_length;
reg tx_odd_parity;
reg tx_even_parity;
reg tx_stick1_parity;
reg tx_stick0_parity;
reg tx_parity_enabled;
reg tx_parity_wrong;
reg tx_framing_wrong;
// TX logic signals
reg [23:0] tx_glitch_num;
reg start_tx_glitch_cnt;
reg [31:0] tx_glitch_cnt;
reg tx_glitch;
reg tx_break_enable;
reg [15:0] tx_break_num;
reg start_tx_break_cnt;
reg [31:0] tx_break_cnt;
reg tx_break;
// TX test signals
reg [7:0] sent_data;
reg tx_accept_next_framing_err;
reg tx_framing_err;
reg tx_framing_glitch_err;
// TX events
event device_sent_packet;
event sent_packet_received;
 
 
// Clock generation
//#################
 
// Example of TESTBENCH's task for setting UART clock period:
// ----------------
// task set_uart_clk_period;
// input [31:0] clk_period;
// begin
// //@(posedge testbench.uart_device.clk);
// testbench.uart_device.T_clk_period = clk_period;
// end
// endtask // set_uart_clk_period
// ----------------
// Example of TESTBENCH's task for setting UART clock rising edge
// delayed for time_delay_i after WB clock rising edge:
// ----------------
// task uart_clk_follows_wb_clk;
// input [31:0] time_delay_i;
// integer time_delay;
// begin
// time_delay = time_delay_i;
// @(posedge testbench.uart_device.clk);
// testbench.uart_device.clk_en = 1'b0;
// @(posedge wb_clk);
// #time_delay testbench.uart_device.clk = 1'b1;
// testbench.uart_device.clk_en = 1'b1;
// end
// endtask // uart_clk_follows_wb_clk
// ----------------
 
// rx_clk rising edge
always@(posedge rx_clk)
if (rx_clk_en)
#(T_clk_period / 2) rx_clk = 1'b0;
// rx_clk falling edge
always@(negedge rx_clk)
if (rx_clk_en)
#(T_clk_period / 2) rx_clk = 1'b1;
 
// tx_clk rising edge
always@(posedge tx_clk)
if (tx_clk_en)
#((T_clk_period + T_clk_delay) / 2) tx_clk = 1'b0;
// tx_clk falling edge
always@(negedge tx_clk)
if (tx_clk_en)
#((T_clk_period + T_clk_delay) / 2) tx_clk = 1'b1;
 
// tx_clk_divided rising edge
always@(posedge tx_clk_divided)
if (tx_clk_divided_en)
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) tx_clk_divided = 1'b0;
// tx_clk_divided falling edge
always@(negedge tx_clk_divided)
if (tx_clk_divided_en)
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) tx_clk_divided = 1'b1;
 
// Inital CLK values
initial
begin:device
rx_clk = 1'b0;
tx_clk = 1'b0;
tx_clk_divided = 1'b0;
end
 
 
// IN/OUT assignments
//###################
 
// UART output
assign srx_o = (tx ^ tx_glitch) & ~tx_break;
// Modem output
assign cts_o = 0;
assign dsr_o = 0;
assign ri_o = 0;
assign dcd_o = 0;
// UART input
assign rx = stx_i;
// Modem input
assign rts = rts_i;
assign dtr = dtr_i;
 
 
// UART receiver
//##############
 
// Initial values for RX
initial
begin
// Default LENGTH
rx_length = 8;
// Default PARITY
rx_odd_parity = 1'b0;
rx_even_parity = 1'b0;
rx_stick1_parity = 1'b0;
rx_stick0_parity = 1'b0;
rx_parity_enabled = 1'b0;
// Default STOP
rx_stop_bit_1 = 1'b1;
rx_stop_bit_1_5 = 1'b0;
rx_stop_bit_2 = 1'b0;
end
 
// Total length of RX packet (for proper generation of the rx_packet_end signal):
// data length + parity + 1 stop bit + second stop bit (when enabled)
assign rx_total_length = rx_length + rx_parity_enabled + 1 + rx_stop_bit_2;
// +1 is used because start bit was not included in rx_total_length.
assign rx_break_detection_length = rx_total_length + 1;
 
// Generating rx_clk_cnt_en signal.
always@(posedge rx_clk)
begin
if (~rx_clk_cnt_en)
begin
wait (~rx);
end
rx_clk_cnt_en = 1;
rx_packet_end = 0;
wait (rx_packet_end);
rx_clk_cnt_en = 0;
wait (rx); // Must be high to continue, because of break condition
end
 
// Counter used in data reception
always@(posedge rx_clk)
begin
if (rx_clk_cnt_en)
begin
if (rx_clk_cnt == (8 * T_divisor - 1) & rx) // False start bit detection
rx_packet_end = 1;
if (rx_clk_cnt_en) // Checking is still enabled after devisor clocks
rx_clk_cnt <= #1 rx_clk_cnt + 1;
else
rx_clk_cnt <= #1 0;
end
else
rx_clk_cnt <= #1 0;
end
 
// Delayed rx_packet_end signal
always@(posedge rx_clk)
rx_packet_end_q = rx_packet_end;
 
// Generating sample clock and end of the frame (Received data is sampled with this clock)
always@(posedge rx_clk)
begin
if (rx_clk_cnt == 8 * T_divisor - 1)
rx_bit_index = 0;
else if (rx_clk_cnt == (8 * T_divisor + 16 * T_divisor * (rx_bit_index + 1) - 1))
begin
rx_sample_clock = 1;
rx_bit_index = rx_bit_index + 1;
if (rx_bit_index == rx_total_length)
rx_packet_end = 1;
end
else
rx_sample_clock = 0;
end
 
// Sampling data (received data)
always@(posedge rx_clk)
begin
if (rx_sample_clock)
begin
if (rx_bit_index <= rx_length) // Sampling data
begin
rx_stop_bit_index <= 0; // Stop bit index reset at the beginning of the data stage
// $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading data bits = %0x", rx_bit_index, rx);
rx_data[rx_bit_index - 1] = rx;
if (rx_bit_index == rx_length)
-> device_received_last_bit;
end
else
begin
if (rx_bit_index == (rx_length + 1))
begin
if (rx_parity_enabled)
begin
// $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading parity bits = %0x", rx_bit_index, rx);
end
else
begin
-> device_received_stop_bit;
rx_stop[rx_stop_bit_index] = rx;
rx_stop_bit_index <= rx_stop_bit_index + 1;
end
rx_parity = rx & rx_parity_enabled;
end
if (rx_bit_index >= (rx_length + 1 + rx_parity_enabled))
begin
// $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading stop bits = %0x", rx_bit_index, rx);
rx_stop[rx_stop_bit_index] = rx;
rx_stop_bit_index <= rx_stop_bit_index + 1;
end
end
end
// Filling the rest of the data with 0
if (rx_length == 5)
rx_data[7:5] = 0;
if (rx_length == 6)
rx_data[7:6] = 0;
if (rx_length == 7)
rx_data[7] = 0;
// Framing error generation
// When 1 or 1.5 stop bits are used, only first stop bit is checked
rx_framing_error = (rx_stop_bit_1 | rx_stop_bit_1_5) ? ~rx_stop[0] : ~(&rx_stop[1:0]);
// Parity error generation
if (rx_odd_parity)
rx_parity_error = ~(^{rx_data, rx_parity});
else if (rx_even_parity)
rx_parity_error = ^{rx_data, rx_parity};
else if (rx_stick0_parity)
rx_parity_error = rx_parity;
else if (rx_stick1_parity)
rx_parity_error = ~rx_parity;
else
rx_parity_error = 0;
end
 
// Break detection
always@(posedge rx_clk)
begin
rx_break_detected_q <= rx_break_detected;
if (rx)
begin
rx_break_cnt = 0; // Reseting counter
rx_break_detected = 0; // Clearing break detected signal
end
else
rx_break_cnt = rx_break_cnt + 1;
if (rx_break_cnt == rx_break_detection_length * 16 * T_divisor)
begin
// $display("\n(%0t) Break_detected.", $time);
rx_break_detected <= 1;
-> device_detected_rx_break;
end
end
// Writing received data
always@(posedge rx_clk)
begin
if ((rx_packet_end & ~rx_packet_end_q) | (rx_break_detected & ~rx_break_detected_q))
begin
wait (rx | rx_break_detected); // Waiting for "end of cycle detected" or "break to be activated"
// rx_break_detected
// rx_length
// rx_parity_enabled
// rx_odd_parity | rx_even_parity | rx_stick1_parity | rx_stick0_parity
// rx_stop_bit_1 | rx_stop_bit_1_5 | rx_stop_bit_2
-> device_received_packet;
end
end
 
 
// UART transmitter
//#################
 
// Initial values for TX
initial
begin
// Default LENGTH
tx_length = 8;
// Default PARITY
tx_odd_parity = 1'b0;
tx_even_parity = 1'b0;
tx_stick1_parity = 1'b0;
tx_stick0_parity = 1'b0;
tx_parity_enabled = 1'b0;
// Default CORRECT PARITY
tx_parity_wrong = 1'b0;
// Default CORRECT FRAME
tx_framing_wrong = 1'b0;
tx_framing_err = 0;
tx_framing_glitch_err = 0;
// Default NO GLITCH
tx_glitch_num = 24'h0;
// Default NO BREAK
tx_break_enable = 1'b0;
tx_break_num = 16'h0;
end
 
// Counter for TX glitch generation
always@(posedge tx_clk or posedge start_tx_glitch_cnt)
begin
if (start_tx_glitch_cnt)
begin
tx_glitch_cnt <= tx_glitch_cnt + 1;
if (tx_glitch_cnt == ((tx_glitch_num - 1) * T_divisor))
tx_glitch = 1'b1;
else if (tx_glitch_cnt == (tx_glitch_num * T_divisor))
begin
tx_glitch = 1'b0;
start_tx_glitch_cnt = 1'b0;
end
end
else
tx_glitch_cnt <= 0;
end
 
// Break setting & break counter
always@(posedge tx_clk)
begin
if (tx_break_enable && (tx_break_cnt == (tx_break_num * T_divisor)))
begin
start_tx_break_cnt = 0;
end
else if (start_tx_break_cnt)
begin
tx_break_cnt = tx_break_cnt + 1;
tx_break = 1;
end
else
begin
tx_break_cnt = 0;
tx_break = 0;
end
end
// Sending packets
task send_packet;
input tx_random_i;
input [7:0] tx_data_i;
input num_of_tx_data_i;
reg [7:0] tx_data;
reg tx_parity_xor;
integer tx_bit_index;
integer num_of_tx_data;
reg last_tx_data;
begin
// SEVERE ERROR
if (// WRONG combinations of parameters for testing
((T_clk_delay != 0) && (tx_parity_wrong || tx_framing_wrong)) ||
((T_clk_delay != 0) && (tx_glitch_num != 0)) ||
((T_clk_delay != 0) && (tx_break_enable)) ||
((tx_parity_wrong || tx_framing_wrong) && (tx_glitch_num != 0)) ||
((tx_parity_wrong || tx_framing_wrong) && (tx_break_enable)) ||
((tx_glitch_num != 0) && (tx_break_enable)) ||
(tx_glitch_num > ((tx_length + 2'h2 + tx_parity_enabled) * 16 * T_divisor)) || // with STOP bit
// (tx_glitch_num > ((tx_length + 2'h1 + tx_parity_enabled) * 16 * T_divisor)) || // without STOP bit
// WRONG input parameters
(num_of_tx_data_i == 0) ||
((num_of_tx_data_i > 1) && tx_break_enable)
)
begin
`SEVERE_ERROR("WRONG combination of parameters for testing UART receiver");
end
for (num_of_tx_data = 0;
num_of_tx_data < num_of_tx_data_i;
num_of_tx_data = (num_of_tx_data + 1'b1))
begin
if (num_of_tx_data == (num_of_tx_data_i - 1'b1))
last_tx_data = 1'b1;
else
last_tx_data = 0;
// TX data
if (~tx_random_i)
tx_data = tx_data_i;
else
tx_data = {$random}%256; // 0..255
// Sending start bit
@(posedge tx_clk_divided);
tx = 0;
if (tx_glitch_num > 0)
start_tx_glitch_cnt = 1; // enabling tx_glitch generation
if (tx_break_enable)
start_tx_break_cnt = 1; // Start counter that counts break tx_length
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
// Sending tx_data bits
for (tx_bit_index = 0; tx_bit_index < tx_length; tx_bit_index = tx_bit_index + 1)
begin
@(posedge tx_clk_divided);
tx = tx_data[tx_bit_index];
end
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
 
sent_data = tx_data;
// Calculating parity
if(tx_length == 5)
begin
tx_parity_xor = ^tx_data[4:0];
end
else if(tx_length == 6)
begin
tx_parity_xor = ^tx_data[5:0];
end
else if(tx_length == 7)
begin
tx_parity_xor = ^tx_data[6:0];
end
else if(tx_length == 8)
begin
tx_parity_xor = ^tx_data[7:0];
end
else
$display("WRONG length of TX data packet");
// Sending parity bit
if (tx_parity_enabled)
begin
@(posedge tx_clk_divided);
if (tx_odd_parity)
tx = tx_parity_wrong ^ (~tx_parity_xor);
else if (tx_even_parity)
tx = tx_parity_wrong ^ tx_parity_xor;
else if (tx_stick1_parity)
tx = tx_parity_wrong ^ 1;
else if (tx_stick0_parity)
tx = tx_parity_wrong ^ 0;
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
end
// Sending stop bit
if (~tx_framing_wrong ||
(tx_glitch_num != ((((tx_length + 2'h2 + tx_parity_enabled) * 2) - 1'b1) * 8 * T_divisor)))
begin
@(posedge tx_clk_divided);
tx = 1;
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
-> device_sent_packet;
@(sent_packet_received);
end
else if (~tx_framing_wrong ||
(tx_glitch_num == ((((tx_length + 2'h2 + tx_parity_enabled) * 2) - 1'b1) * 8 * T_divisor)))
begin
@(posedge tx_clk_divided);
tx = 1;
// Wait for 1 bit
@(posedge tx_clk_divided); // this will be like 2. stop bit
-> device_sent_packet;
@(sent_packet_received);
end
else if (tx_framing_wrong && last_tx_data)
begin
@(posedge tx_clk_divided);
// Wrong stop | start bit
tx = 0;
@(posedge tx_clk_divided);
-> device_sent_packet;
@(sent_packet_received);
tx_framing_wrong = 0;
// TX data
tx = 1;
tx_data = 8'hFF;
// Sending tx_data bits
for (tx_bit_index = 0; tx_bit_index < tx_length; tx_bit_index = tx_bit_index + 1)
begin
@(posedge tx_clk_divided);
tx = tx_data[tx_bit_index];
end
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
sent_data = tx_data;
// Calculating parity
if(tx_length == 5)
begin
tx_parity_xor = ^tx_data[4:0];
end
else if(tx_length == 6)
begin
tx_parity_xor = ^tx_data[5:0];
end
else if(tx_length == 7)
begin
tx_parity_xor = ^tx_data[6:0];
end
else if(tx_length == 8)
begin
tx_parity_xor = ^tx_data[7:0];
end
else
$display("WRONG length of TX data packet");
// Sending parity bit
if (tx_parity_enabled)
begin
@(posedge tx_clk_divided);
if (tx_odd_parity)
tx = tx_parity_wrong ^ (~tx_parity_xor);
else if (tx_even_parity)
tx = tx_parity_wrong ^ tx_parity_xor;
else if (tx_stick1_parity)
tx = tx_parity_wrong ^ 1;
else if (tx_stick0_parity)
tx = tx_parity_wrong ^ 0;
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
end
// Stop bit
@(posedge tx_clk_divided);
tx = 1;
// Wait for almost 1 bit
#(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor); // wait half period
#((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
-> device_sent_packet;
@(sent_packet_received);
tx_framing_wrong = 1'b1;
end
else if (last_tx_data)
begin
@(posedge tx_clk_divided);
-> device_sent_packet;
@(sent_packet_received);
end
end
end
endtask // send_packet
 
 
endmodule
/trunk/bench/verilog/uart_testbench.v
0,0 → 1,1363
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_testbench.v ////
//// ////
//// This file is part of the "uart16550" project ////
//// http://www.opencores.org/projects/uart16550/ ////
//// ////
//// Author(s): ////
//// - tadej@opencores.org (Tadej Markovic) ////
//// ////
//// All additional information is avaliable in the README.txt ////
//// file. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 - 2004 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
 
`include "uart_defines.v"
`include "uart_testbench_defines.v"
`include "wb_model_defines.v"
`include "timescale.v"
 
module testbench;
 
 
parameter max_wait_cnt = 20000;
 
// INTERNAL signals
//#################
 
// WB slave signals
//#################
 
// UART Wishbone Slave signals
wire wb_int_o;
wire [`UART_ADDR_WIDTH-1:0] wbs_adr_i;
wire [`UART_DATA_WIDTH-1:0] wbs_dat_i;
wire [`UART_DATA_WIDTH-1:0] wbs_dat_o;
wire [3:0] wbs_sel_i;
wire wbs_cyc_i;
wire wbs_stb_i;
wire [2:0] wbs_cti_i;
wire [1:0] wbs_bte_i;
wire wbs_we_i;
wire wbs_ack_o;
wire wbs_rty_o = 1'b0;
wire wbs_err_o = 1'b0;
 
// UART signals
//#############
 
// UART Serial Data I/O signals
wire stx_pad_o;
wire srx_pad_i;
// UART Modem I/O signals
wire rts_pad_o;
wire cts_pad_i;
wire dtr_pad_o;
wire dsr_pad_i;
wire ri_pad_i;
wire dcd_pad_i;
`ifdef UART_HAS_BAUDRATE_OUTPUT
wire baud_o;
`endif
 
// System signals
//###############
 
// WB clock signal
reg wb_clk; // divided device clock with period T_wb_clk_period
// WB clock enable signal
reg wb_clk_en = 1'b1;
// WB clock period variable
real T_wb_clk_period = 20;
// WB reset signal
reg wb_reset;
event reset_aserted;
event reset_released;
event int_aserted;
event int_released;
// Error detection event
event error_detected;
 
// UART register monitor
//#########################
 
// Line Status Register
// Reading LSR register
reg lsr_reg_read;
// Bit 0 - Data Ready
reg lsr_reg_bit0_change_allowed;
// Bit 1 - Overrun Error
reg lsr_reg_bit1_change_allowed;
// Bit 2 - Parity Error
reg lsr_reg_bit2_change_allowed;
reg [4:0] rx_fifo_par_rd_pointer;
integer i2;
// Bit 3 - Framing Error
reg lsr_reg_bit3_change_allowed;
reg [4:0] rx_fifo_frm_rd_pointer;
integer i3;
// Bit 4 - Break Interrupt
reg lsr_reg_bit4_change_allowed;
reg [4:0] rx_fifo_brk_rd_pointer;
integer i4;
// Bit 5 - Transmitter Holding Register Empty
reg lsr_reg_bit5_change_allowed;
// Bit 6 - Transmitter Empty
reg lsr_reg_bit6_change_allowed;
// Bit 7 - Error in RX FIFO
reg lsr_reg_bit7_change_allowed;
 
// UART transmitter monitor
//#########################
 
// TX FIFO signals
reg [7:0] tx_shift_reg;
reg tx_shift_reg_empty;
reg tx_start_bit_edge;
reg [7:0] tx_fifo [0:31];
reg [4:0] tx_fifo_wr_pointer;
reg [4:0] tx_fifo_rd_pointer;
reg [4:0] tx_fifo_status;
 
// UART receiver monitor
//######################
 
// RX FIFO signals
reg [7:0] rx_shift_reg;
reg rx_shift_reg_full;
reg rx_parity_err;
reg rx_framing_err;
reg rx_framing_glitch;
reg rx_break_int;
reg rx_overrun_err_occured;
reg [7:0] rx_fifo_data [0:31];
reg [31:0] rx_fifo_par;
reg [31:0] rx_fifo_frm;
reg [31:0] rx_fifo_brk;
reg [4:0] rx_fifo_wr_pointer;
reg [4:0] rx_fifo_rd_pointer;
reg [4:0] rx_fifo_status;
reg rx_fifo_read;
 
// UART register tracker
//######################
 
// Registers
wire [7:0] ier_reg;
wire [7:0] iir_reg;
wire [7:0] fcr_reg;
wire [7:0] lcr_reg;
wire [7:0] mcr_reg;
wire [7:0] lsr_reg;
wire [7:0] msr_reg;
wire [7:0] dll_reg;
wire [7:0] dlm_reg;
// Events
event ier_reg_changed;
event iir_reg_changed;
event fcr_reg_changed;
event lcr_reg_changed;
event mcr_reg_changed;
event lsr_reg_changed;
event msr_reg_changed;
event dll_reg_changed;
event dlm_reg_changed;
// Register access
reg [`UART_ADDR_WIDTH-1:0] reg_adr;
reg [`UART_DATA_WIDTH-1:0] reg_dat;
reg reg_dlab;
event reg_written;
event tx_reg_written;
event reg_read;
event rx_reg_read;
 
 
 
uart_top #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH) i_uart_top
(
.wb_clk_i (wb_clk),
.wb_rst_i (wb_reset),
.int_o (wb_int_o),
// WB slave signals - 2 address locations for two registers!
.wb_cyc_i (wbs_cyc_i),
.wb_stb_i (wbs_stb_i),
.wb_we_i (wbs_we_i),
.wb_sel_i (wbs_sel_i),
.wb_adr_i (wbs_adr_i),
.wb_dat_i (wbs_dat_i),
.wb_dat_o (wbs_dat_o),
.wb_ack_o (wbs_ack_o),
// UART signals
.stx_pad_o (stx_pad_o),
.srx_pad_i (srx_pad_i),
// Modem signals
.rts_pad_o (rts_pad_o),
.cts_pad_i (cts_pad_i),
.dtr_pad_o (dtr_pad_o),
.dsr_pad_i (dsr_pad_i),
.ri_pad_i (ri_pad_i),
.dcd_pad_i (dcd_pad_i)
`ifdef UART_HAS_BAUDRATE_OUTPUT
,
.baud_o (baud_o)
`endif
);
 
uart_device i_uart_device
(
// UART signals
.stx_i (stx_pad_o),
.srx_o (srx_pad_i),
// Modem signals
.rts_i (rts_pad_o),
.cts_o (cts_pad_i),
.dtr_i (dtr_pad_o),
.dsr_o (dsr_pad_i),
.ri_o (ri_pad_i),
.dcd_o (dcd_pad_i)
);
 
wb_master_model #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH, 4) i_wb_master_model
(
.wb_rst_i (wb_reset),
.wb_clk_i (wb_clk),
.wbm_cyc_o (wbs_cyc_i),
.wbm_cti_o (),
.wbm_bte_o (),
.wbm_stb_o (wbs_stb_i),
.wbm_we_o (wbs_we_i),
.wbm_adr_o (wbs_adr_i),
.wbm_sel_o (wbs_sel_i),
.wbm_dat_o (wbs_dat_i),
.wbm_dat_i (wbs_dat_o),
.wbm_ack_i (wbs_ack_o),
.wbm_err_i (wbs_err_o), // inactive (1'b0)
.wbm_rty_i (wbs_rty_o) // inactive (1'b0)
);
 
 
initial
begin:system
// Initial system values
wb_reset = 1'b1;
wb_clk = 1'b0;
end
 
 
// WB clock generation (DEVICE clock is generated in uart_device.v)
//#################################################################
 
// DEVICE's clock generation:
// ----------------
// // rx_clk rising edge
// always@(posedge rx_clk)
// if (rx_clk_en)
// #(T_clk_period / 2) rx_clk = 1'b0;
// // rx_clk falling edge
// always@(negedge rx_clk)
// if (rx_clk_en)
// #(T_clk_period / 2) rx_clk = 1'b1;
// ----------------
// DEVICE's transmit clocks generation:
// ----------------
// // tx_clk rising edge
// always@(posedge tx_clk)
// if (tx_clk_en)
// #((T_clk_period / 2) * 16 * T_divisor) tx_clk = 1'b0;
// // tx_clk falling edge
// always@(negedge tx_clk)
// if (tx_clk_en)
// #((T_clk_period / 2) * 16 * T_divisor) tx_clk = 1'b1;
// ----------------
 
// WB clock
always@(posedge wb_clk)
if (wb_clk_en)
#(T_wb_clk_period / 2) wb_clk = 1'b0;
always@(negedge wb_clk)
if (wb_clk_en)
#(T_wb_clk_period / 2) wb_clk = 1'b1;
 
 
// SYSTEM signals tracker
//#######################
 
// Reset
always@(posedge wb_reset)
-> reset_aserted;
always@(negedge wb_reset)
-> reset_released;
 
// Interrupt
always@(posedge wb_int_o)
-> int_aserted;
always@(negedge wb_int_o)
-> int_released;
 
 
// UART register tracker
//######################
 
// UART registers:
// ----------------
// RBR (R/ | ADR 0 | DLAB 0)
// [7:0] -RX---- "rxdata" Receiver Buffer Register
// ----------------
// THR ( /W | ADR 0 | DLAB 0)
// [7:0] ----TX- "txdata" Transmitter Holding Register
// ----------------
// IER (R/W | ADR 1 | DLAB 0)
// [0] -RX---- "1" Received Data Available & Receive Fifo Timeout
// [1] ----TX- "1" Transmitter Holding Register Empty
// [2] -RX---- "1" Receiver Line Status
// [3] -MODEM- "1" Modem Status
// ----------------
// IIR (R/ | ADR 2)
// [0] ------- "0" Interrupt is Pending (decreasing priority level in following 3 bits)
// [3:1] -RX---- "011" Receiver Line Status - Overrun, Parity, Framing error or Break int. ---> READ LSR
// [3:1] -RX---- "010" Received Data Available - Fifo Trigger Level Reached ------------------> READ RBR (Fifo lower than trig.)
// [3:1] -RX---- "110" Timeout Indication - Fifo not empty & no Fifo action for 4 char times -> READ RBR
// [3:1] ----TX- "001" Transmitter Holding Register Empty - THR Empty ------------------------> READ IIR | WRITE THR
// [3:1] -MODEM- "000" Modem Status - CTS, DSR, DCD changed or RI changed from '0' to '1' ----> READ MSR
// ----------------
// FCR ( /W | ADR 2)
// [1] -RX---- "1" Clear only Receiver Fifo (not shift register)
// [2] ----TX- "1" Clear only Transmitter Fifo (not shift register)
// [7:6] -RX---- "00" 1 BYTE Receiver Fifo Interrupt trigger level
// [7:6] -RX---- "01" 4 BYTEs Receiver Fifo Interrupt trigger level
// [7:6] -RX---- "10" 8 BYTEs Receiver Fifo Interrupt trigger level
// [7:6] -RX---- "11" 14 BYTEs Receiver Fifo Interrupt trigger level
// ----------------
// LCR (R/W | ADR 3)
// [1:0] -RX-TX- "00" 5 bits in each character
// [1:0] -RX-TX- "01" 6 bits in each character
// [1:0] -RX-TX- "10" 7 bits in each character
// [1:0] -RX-TX- "11" 8 bits in each character
// [2] -RX-TX- "0" 1 stop bit
// [2] -RX-TX- "1" 1.5 stop bits (when 5 bits of char.) or 2 stop bits (when 6, 7 or 8 bits of char.)
// [3] -RX-TX- "1" Parity bit enabled
// [5:4] -RX-TX- "00" NO Stick Parity & ODD Parity bit - ODD num. of '1's is transmitted
// [5:4] -RX-TX- "01" NO Stick Parity & EVEN Parity bit - EVEN num. of '1's is transmitted
// [5:4] -RX-TX- "10" Stick Parity bit - Stick '1' as Parity bit
// [5:4] -RX-TX- "11" Stick Parity bit - Stick '0' as Parity bit
// [6] ----TX- "1" Break Control - Output is forced to '0'
// [7] ------- "1" DLAB - for access to DLL and DLM
// ----------------
// MCR ( /W | ADR 4)
// [0] -MODEM- "1" Force DTR to '0' - in LoopBack connected to DSR input
// [1] -MODEM- "1" Force RTS to '0' - in LoopBack connected to CTS input
// [2] -MODEM- "1" Force N.C.1 to '0' - in LoopBack connected to RI input
// [3] -MODEM- "1" Force N.C.2 to '0' - in LoopBack connected to DCD input
// [4] -MODEM- "1" LoopBack mode
// ----------------
// LSR (R/ | ADR 5)
// [0] -RX---- "1" Data Ready - At least 1 char. received and is in Fifo----------> READ RBR (Fifo empty)
// [1] -RX---- "1" Overrun Error - Fifo full & 1 char. received in shift reg. ----> READ LSR
// [2] -RX---- "1" Parity Error - top Fifo char. has invalid parity bit ----------> READ LSR
// [3] -RX---- "1" Framing Error - top Fifo char. has invalid stop bit -----------> READ LSR
// [4] -RX---- "1" Break Int. - top Fifo char. bits are '0' and it's ctrl. bits --> READ LSR
// [5] ----TX- "1" Transmitter Holding Register Empty - transmitter Fifo empty ---> WRITE THR
// [6] ----TX- "1" Transmitter EMpTy - transmitter Fifo empty & shift reg. empty -> WRITE THR
// [7] -RX---- "1" At least 1 Parity Error, Framing Error or Break Int. in Fifo --> READ LSR & No More Errors in Fifo
// ----------------
// MSR (R/ | ADR 6)
// [0] -MODEM- "1" Delta CTS indicator - CTS has changed it's state --------------> READ MSR
// [1] -MODEM- "1" Delta DSR indicator - DSR has changed it's state --------------> READ MSR
// [2] -MODEM- "1" Trailing Edge of RI - RI has changed from '0' to '1' ----------> READ MSR
// [3] -MODEM- "1" Delta DCD indicator - DCD has changed it's state --------------> READ MSR
// [4] -MODEM- "x" Complement of CTS input | in LoopBack equal to RTS = MCR[1]
// [5] -MODEM- "x" Complement of DSR input | in LoopBack equal to DTR = MCR[0]
// [6] -MODEM- "x" Complement of RI input | in LoopBack equal to N.C.1 = MCR[2]
// [7] -MODEM- "x" Complement of DCD input | in LoopBack equal to N.C.2 = MCR[3]
// ----------------
// DLL (R/W | ADR 0 | DLAB 1)
// [7:0] ------- "dl[ 7:0]" LSB of DL Reg. written 2. - dl == '0' disables outputs / dl = 1/(T_wb_clk_period*16*BaudRate)
// ----------------
// DLM (R/W | ADR 1 | DLAB 1)
// [7:0] ------- "dl[15:8]" MSB of DL Reg. written 1. - dl == '0' disables outputs / dl = 1/(T_wb_clk_period*16*BaudRate)
// ----------------
 
// Transparent UART registers
assign ier_reg[7:0] = {4'h0, testbench.i_uart_top.regs.ier };
assign iir_reg[7:0] = {4'hC, testbench.i_uart_top.regs.iir };
assign fcr_reg[7:0] = { testbench.i_uart_top.regs.fcr, 6'h0};
assign lcr_reg[7:0] = { testbench.i_uart_top.regs.lcr }; // lcr_reg[7] == DLAB !!!
assign mcr_reg[7:0] = {3'h0, testbench.i_uart_top.regs.mcr };
assign lsr_reg[7:0] = { testbench.i_uart_top.regs.lsr };
assign msr_reg[7:0] = { testbench.i_uart_top.regs.msr };
assign dll_reg[7:0] = { testbench.i_uart_top.regs.dl[ 7:0] };
assign dlm_reg[7:0] = { testbench.i_uart_top.regs.dl[15:8] };
 
// Tracking changes of registers
always@(ier_reg)
begin
-> ier_reg_changed;
end
always@(iir_reg)
begin
-> iir_reg_changed;
end
always@(fcr_reg)
begin
-> fcr_reg_changed;
end
always@(lcr_reg)
begin
-> lcr_reg_changed;
end
always@(mcr_reg)
begin
-> mcr_reg_changed;
end
always@(lsr_reg)
begin
-> lsr_reg_changed;
end
always@(msr_reg)
begin
-> msr_reg_changed;
end
always@(dll_reg)
begin
-> dll_reg_changed;
end
always@(dlm_reg)
begin
-> dlm_reg_changed;
end
 
// Tracking read/write access to registers
always@(wbs_cyc_i or wbs_stb_i or wbs_we_i or wbs_sel_i or wbs_adr_i or
wbs_dat_i /*or wbs_ack_o*/ /*or posedge wb_clk*/)
begin
if (wbs_cyc_i && wbs_stb_i)
begin
if (wbs_we_i /*&& wbs_ack_o*/) // WRITE
begin
// LOG's example of detecting of register write:
// ----------------
// case (wbs_adr_i)
// `UART_REG_TR: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!
// -> dll_reg_written;
// else
// -> thr_reg_written;
// `UART_REG_IE: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!
// -> dlm_reg_written;
// else
// -> ier_reg_written;
// `UART_REG_FC: -> fcr_reg_written;
// `UART_REG_LC: -> lcr_reg_written;
// `UART_REG_MC: -> mcr_reg_written;
// default: -> erroneous_write_location;
// endcase
// ----------------
 
reg_adr = wbs_adr_i;
reg_dat = wbs_dat_i;
reg_dlab = lcr_reg[7];
-> reg_written;
if (~reg_dlab && (reg_adr == `UART_REG_TR)) // write to FIFO
-> tx_reg_written;
end
end
end
always@(wbs_cyc_i or wbs_stb_i or wbs_we_i or wbs_sel_i or wbs_adr_i or
wbs_dat_o or wbs_ack_o /*or posedge wb_clk*/)
begin
if (wbs_cyc_i && wbs_stb_i)
begin
if (~wbs_we_i && wbs_ack_o) // READ
begin
// LOG's example of detecting of register read:
// ----------------
// case (wbs_adr_i)
// `UART_REG_RB: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!
// -> dll_reg_read;
// else
// -> rbr_reg_read;
// `UART_REG_IE: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!
// -> dlm_reg_read;
// else
// -> ier_reg_read;
// `UART_REG_II: -> iir_reg_read;
// `UART_REG_LC: -> lcr_reg_read;
// `UART_REG_LS: -> lsr_reg_read;
// `UART_REG_MS: -> msr_reg_read;
// default: -> erroneous_read_location;
// endcase
// ----------------
 
reg_adr = wbs_adr_i;
reg_dat = wbs_dat_o;
reg_dlab = lcr_reg[7];
-> reg_read;
if (~reg_dlab && (reg_adr == `UART_REG_RB))
-> rx_reg_read;
end
end
end
 
 
// UART register monitor
//#######################
 
// Line Status Register
// Reading LSR register
initial
begin
lsr_reg_read = 0;
forever
begin
@(reg_read);
if (reg_adr == `UART_REG_LS)
begin
lsr_reg_read = 1'b1;
repeat (1) @(posedge wb_clk);
lsr_reg_read = 0;
end
end
end
// Bit 0 - Data Ready
initial
begin
lsr_reg_bit0_change_allowed = 0;
@(reset_released);
#10;
fork
begin: rx_fifo_status_changing
forever
begin
if (rx_fifo_status == 0)
begin
wait (rx_fifo_status > 0);
lsr_reg_bit0_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit0_change_allowed = 0;
if (~lsr_reg[0])
begin
`BENCH_ERROR("Bit 0 of LSR register not '1'!");
-> error_detected;
end
end
else
begin
wait (rx_fifo_status == 0);
lsr_reg_bit0_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit0_change_allowed = 0;
if (lsr_reg[0])
begin
`BENCH_ERROR("Bit 0 of LSR register not '0'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit0_changing
forever
begin
wait (~lsr_reg_bit0_change_allowed);
begin
@(lsr_reg[0] or lsr_reg_bit0_change_allowed);
if (~lsr_reg_bit0_change_allowed)
begin
`BENCH_ERROR("Bit 0 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 1 - Overrun Error
initial
begin
lsr_reg_bit1_change_allowed = 0;
@(reset_released);
#10;
fork
begin: rx_overrun_err_occured_changing
forever
begin
if (~rx_overrun_err_occured)
begin
wait (rx_overrun_err_occured);
lsr_reg_bit1_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit1_change_allowed = 0;
if (~lsr_reg[1])
begin
`BENCH_ERROR("Bit 1 of LSR register not '1'!");
-> error_detected;
end
end
else
begin
wait (lsr_reg_read);
lsr_reg_bit1_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit1_change_allowed = 0;
rx_overrun_err_occured = 0;
if (lsr_reg[1])
begin
`BENCH_ERROR("Bit 1 of LSR register not '0'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit1_changing
forever
begin
wait (~lsr_reg_bit1_change_allowed);
begin
@(lsr_reg[1] or lsr_reg_bit1_change_allowed);
if (~lsr_reg_bit1_change_allowed)
begin
`BENCH_ERROR("Bit 1 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 2 - Parity Error
initial
begin
lsr_reg_bit2_change_allowed = 0;
rx_fifo_par_rd_pointer = 0;
@(reset_released);
#10;
fork
begin: rx_parity_err_changing
forever
begin
if (~rx_fifo_par[rx_fifo_par_rd_pointer])
begin
wait (rx_fifo_read);
lsr_reg_bit2_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit2_change_allowed = 0;
rx_fifo_par_rd_pointer = rx_fifo_par_rd_pointer + 1'b1;
// check bit
if (~lsr_reg[2] && rx_fifo_par[rx_fifo_par_rd_pointer])
begin
`BENCH_ERROR("Bit 2 of LSR register not '1'!");
-> error_detected;
end
else if (lsr_reg[2] && ~rx_fifo_par[rx_fifo_par_rd_pointer])
begin
`BENCH_ERROR("Bit 2 of LSR register not '0'!");
-> error_detected;
end
end
else
begin
wait (lsr_reg_read);
lsr_reg_bit2_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit2_change_allowed = 0;
if (rx_fifo_par_rd_pointer < rx_fifo_rd_pointer)
begin
for (i2 = rx_fifo_par_rd_pointer; i2 <= rx_fifo_rd_pointer; i2 = i2 + 1)
rx_fifo_par[i2] = 0;
rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
end
else if (rx_fifo_par_rd_pointer > rx_fifo_rd_pointer)
begin
for (i2 = rx_fifo_par_rd_pointer; i2 <= 31; i2 = i2 + 1)
rx_fifo_par[i2] = 0;
for (i2 = 0; i2 <= rx_fifo_rd_pointer; i2 = i2 + 1)
rx_fifo_par[i2] = 0;
rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
end
else
begin
rx_fifo_par = 0;
rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
end
// check bit
if (~lsr_reg[2] && rx_fifo_par[rx_fifo_par_rd_pointer])
begin
`BENCH_ERROR("Bit 2 of LSR register not '1'!");
-> error_detected;
end
else if (lsr_reg[2] && ~rx_fifo_par[rx_fifo_par_rd_pointer])
begin
`BENCH_ERROR("Bit 2 of LSR register not '0'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit2_changing
forever
begin
wait (~lsr_reg_bit2_change_allowed);
begin
@(lsr_reg[2] or lsr_reg_bit2_change_allowed);
if (~lsr_reg_bit2_change_allowed)
begin
`BENCH_ERROR("Bit 2 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 3 - Framing Error
initial
begin
lsr_reg_bit3_change_allowed = 0;
rx_fifo_frm_rd_pointer = 0;
@(reset_released);
#10;
fork
begin: rx_framing_err_changing
forever
begin
if (~rx_fifo_frm[rx_fifo_frm_rd_pointer])
begin
wait (rx_fifo_read);
lsr_reg_bit3_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit3_change_allowed = 0;
rx_fifo_frm_rd_pointer = rx_fifo_frm_rd_pointer + 1'b1;
// check bit
if (~lsr_reg[3] && rx_fifo_frm[rx_fifo_frm_rd_pointer])
begin
`BENCH_ERROR("Bit 3 of LSR register not '1'!");
-> error_detected;
end
else if (lsr_reg[3] && ~rx_fifo_frm[rx_fifo_frm_rd_pointer])
begin
`BENCH_ERROR("Bit 3 of LSR register not '0'!");
-> error_detected;
end
end
else
begin
wait (lsr_reg_read);
lsr_reg_bit3_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit3_change_allowed = 0;
if (rx_fifo_frm_rd_pointer < rx_fifo_rd_pointer)
begin
for (i3 = rx_fifo_frm_rd_pointer; i3 <= rx_fifo_rd_pointer; i3 = i3 + 1)
rx_fifo_frm[i3] = 0;
rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
end
else if (rx_fifo_frm_rd_pointer > rx_fifo_rd_pointer)
begin
for (i3 = rx_fifo_frm_rd_pointer; i3 <= 31; i3 = i3 + 1)
rx_fifo_frm[i3] = 0;
for (i3 = 0; i3 <= rx_fifo_rd_pointer; i3 = i3 + 1)
rx_fifo_frm[i3] = 0;
rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
end
else
begin
rx_fifo_frm = 0;
rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
end
// check bit
if (~lsr_reg[3] && rx_fifo_frm[rx_fifo_frm_rd_pointer])
begin
`BENCH_ERROR("Bit 3 of LSR register not '1'!");
-> error_detected;
end
else if (lsr_reg[3] && ~rx_fifo_frm[rx_fifo_frm_rd_pointer])
begin
`BENCH_ERROR("Bit 3 of LSR register not '0'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit3_changing
forever
begin
wait (~lsr_reg_bit3_change_allowed);
begin
@(lsr_reg[3] or lsr_reg_bit3_change_allowed);
if (~lsr_reg_bit3_change_allowed)
begin
`BENCH_ERROR("Bit 3 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 4 - Break Interrupt
initial
begin
lsr_reg_bit4_change_allowed = 0;
rx_fifo_brk_rd_pointer = 0;
@(reset_released);
#10;
fork
begin: rx_break_int_changing
forever
begin
if (~rx_fifo_brk[rx_fifo_brk_rd_pointer])
begin
wait (rx_fifo_read);
lsr_reg_bit4_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit4_change_allowed = 0;
rx_fifo_brk_rd_pointer = rx_fifo_brk_rd_pointer + 1'b1;
// check bit
if (~lsr_reg[4] && rx_fifo_brk[rx_fifo_brk_rd_pointer])
begin
`BENCH_ERROR("Bit 4 of LSR register not '1'!");
-> error_detected;
end
else if (lsr_reg[4] && ~rx_fifo_brk[rx_fifo_brk_rd_pointer])
begin
`BENCH_ERROR("Bit 4 of LSR register not '0'!");
-> error_detected;
end
end
else
begin
wait (lsr_reg_read);
lsr_reg_bit4_change_allowed = 1'b1;
repeat (1) @(posedge wb_clk);
#2;
lsr_reg_bit4_change_allowed = 0;
if (rx_fifo_brk_rd_pointer < rx_fifo_rd_pointer)
begin
for (i4 = rx_fifo_brk_rd_pointer; i4 <= rx_fifo_rd_pointer; i4 = i4 + 1)
rx_fifo_brk[i4] = 0;
rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
end
else if (rx_fifo_brk_rd_pointer > rx_fifo_rd_pointer)
begin
for (i4 = rx_fifo_brk_rd_pointer; i4 <= 31; i4 = i4 + 1)
rx_fifo_brk[i4] = 0;
for (i4 = 0; i4 <= rx_fifo_rd_pointer; i4 = i4 + 1)
rx_fifo_brk[i4] = 0;
rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
end
else
begin
rx_fifo_brk = 0;
rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
end
// check bit
if (~lsr_reg[4] && rx_fifo_brk[rx_fifo_brk_rd_pointer])
begin
`BENCH_ERROR("Bit 4 of LSR register not '1'!");
-> error_detected;
end
else if (lsr_reg[4] && ~rx_fifo_brk[rx_fifo_brk_rd_pointer])
begin
`BENCH_ERROR("Bit 4 of LSR register not '0'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit4_changing
forever
begin
wait (~lsr_reg_bit4_change_allowed);
begin
@(lsr_reg[4] or lsr_reg_bit4_change_allowed);
if (~lsr_reg_bit4_change_allowed)
begin
`BENCH_ERROR("Bit 4 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 5 - Transmitter Holding Register Empty
initial
begin
lsr_reg_bit5_change_allowed = 0;
@(reset_released);
#10;
fork
begin: tx_fifo_status_changing
forever
begin
if (tx_fifo_status == 0)
begin
// @(tx_reg_written);
wait (tx_fifo_status > 0);
lsr_reg_bit5_change_allowed = 1'b1;
repeat (3) @(posedge wb_clk);
#2;
lsr_reg_bit5_change_allowed = 0;
if (lsr_reg[5])
begin
`BENCH_ERROR("Bit 5 of LSR register not '0'!");
-> error_detected;
end
end
else
begin
wait (tx_fifo_status == 0);
lsr_reg_bit5_change_allowed = 1'b1;
repeat (3) @(posedge wb_clk);
#2;
lsr_reg_bit5_change_allowed = 0;
if (~lsr_reg[5])
begin
`BENCH_ERROR("Bit 5 of LSR register not '1'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit5_changing
forever
begin
wait (~lsr_reg_bit5_change_allowed);
begin
@(lsr_reg[5] or lsr_reg_bit5_change_allowed);
if (~lsr_reg_bit5_change_allowed)
begin
`BENCH_ERROR("Bit 5 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 6 - Transmitter Empty
initial
begin
lsr_reg_bit6_change_allowed = 0;
@(reset_released);
#10;
fork
begin: tx_fifo_status_and_shift_reg_changing
forever
begin
if ((tx_fifo_status == 0) && tx_shift_reg_empty)
begin
// @(tx_reg_written);
wait (tx_fifo_status > 0);
lsr_reg_bit6_change_allowed = 1'b1;
repeat (3) @(posedge wb_clk);
#2;
lsr_reg_bit6_change_allowed = 0;
if (lsr_reg[6])
begin
`BENCH_ERROR("Bit 6 of LSR register not '0'!");
-> error_detected;
end
end
else
begin
wait ((tx_fifo_status == 0) && tx_shift_reg_empty);
lsr_reg_bit6_change_allowed = 1'b1;
repeat (3) @(posedge wb_clk);
#2;
lsr_reg_bit6_change_allowed = 0;
if (~lsr_reg[6])
begin
`BENCH_ERROR("Bit 6 of LSR register not '1'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit6_changing
forever
begin
wait (~lsr_reg_bit6_change_allowed);
begin
@(lsr_reg[6] or lsr_reg_bit6_change_allowed);
if (~lsr_reg_bit6_change_allowed)
begin
`BENCH_ERROR("Bit 6 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
// Bit 7 - Error in RX FIFO
initial
begin
lsr_reg_bit7_change_allowed = 0;
@(reset_released);
#10;
fork
begin: error_changing
forever
begin
if ((rx_fifo_par == 0) && (rx_fifo_frm == 0) && (rx_fifo_brk == 0))
begin
wait (rx_parity_err || rx_framing_err || rx_framing_glitch || rx_break_int);
lsr_reg_bit7_change_allowed = 1'b1;
repeat (3) @(posedge wb_clk);
#2;
lsr_reg_bit7_change_allowed = 0;
// check bit
if (~lsr_reg[7])
begin
`BENCH_ERROR("Bit 7 of LSR register not '1'!");
-> error_detected;
end
end
else
begin
wait (lsr_reg_read && (rx_fifo_par == 0) && (rx_fifo_frm == 0) && (rx_fifo_brk == 0));
lsr_reg_bit7_change_allowed = 1'b1;
repeat (2) @(posedge wb_clk);
#2;
lsr_reg_bit7_change_allowed = 0;
// check bit
if (lsr_reg[7])
begin
`BENCH_ERROR("Bit 7 of LSR register not '0'!");
-> error_detected;
end
end
end
end
begin: lsr_reg_bit7_changing
forever
begin
wait (~lsr_reg_bit7_change_allowed);
begin
@(lsr_reg[7] or lsr_reg_bit7_change_allowed);
if (~lsr_reg_bit7_change_allowed)
begin
`BENCH_ERROR("Bit 7 of LSR register should not change!");
-> error_detected;
end
end
end
end
join
end
 
 
// UART transmitter monitor
//#########################
 
// TX FIFO status
always@(tx_fifo_wr_pointer or tx_fifo_rd_pointer)
begin
if (tx_fifo_wr_pointer >= tx_fifo_rd_pointer)
tx_fifo_status = tx_fifo_wr_pointer - tx_fifo_rd_pointer;
else
tx_fifo_status = (5'h1F - tx_fifo_rd_pointer) + tx_fifo_wr_pointer;
end
// TX FIFO and TX data
initial
begin
tx_fifo_wr_pointer = 0;
tx_fifo_rd_pointer = 0;
tx_shift_reg_empty = 1;
tx_fifo_status = 0;
tx_start_bit_edge = 1;
fork
begin:write_tx_shift_reg_read_tx_fifo
forever
begin
wait ((tx_fifo_status !== 0) && tx_shift_reg_empty && tx_start_bit_edge && ~stx_pad_o);
tx_start_bit_edge = 0;
tx_shift_reg = tx_fifo[tx_fifo_rd_pointer];
tx_shift_reg_empty = 0;
@(testbench.i_uart_device.device_received_last_bit);
repeat (16393) @(posedge wb_clk);
tx_fifo_rd_pointer = tx_fifo_rd_pointer + 1'b1;
@(posedge wb_clk);
if (tx_fifo_status == 0)
begin
`BENCH_MSG("TX FIFO is empty!");
end
end
end
begin:write_tx_fifo
forever
begin
@(tx_reg_written); // write to FIFO
repeat (1) @(posedge wb_clk); // delay when writing into registers
if (tx_fifo_status <= 5'h0F)
begin
tx_fifo[tx_fifo_wr_pointer] = reg_dat;
tx_fifo_wr_pointer = tx_fifo_wr_pointer + 1'b1;
end
else // FIFO overflow
begin
`BENCH_WARNING("TX FIFO overflow!");
end
end
end
begin:empty_tx_fifo
forever
begin
wait (fcr_reg[2]);
tx_fifo_wr_pointer = 0;
tx_fifo_rd_pointer = 0;
@(posedge wb_clk);
if (tx_fifo_status == 0)
begin
`BENCH_MSG("TX FIFO is empty!");
end
end
end
begin:read_tx_shift_reg
forever
begin
@(testbench.i_uart_device.device_received_packet);
// Check data
if (tx_shift_reg != testbench.i_uart_device.rx_data)
begin
`BENCH_ERROR("TX data has ERROR!");
-> error_detected;
end
else
`BENCH_MSG("TX data correct!");
if (testbench.i_uart_device.rx_parity_error)
begin
`BENCH_ERROR("TX data has parity ERROR!");
-> error_detected;
end
else
`BENCH_MSG("TX data parity correct!");
if (testbench.i_uart_device.rx_framing_error)
begin
`BENCH_ERROR("TX data has framing ERROR!");
-> error_detected;
end
else
`BENCH_MSG("TX data framing correct!");
// Set TX FIFO read pointer
tx_start_bit_edge = 1;
repeat (7) @(wb_clk);
if (tx_shift_reg_empty == 0)
begin
tx_shift_reg_empty = 1'b1;
end
else
begin
`BENCH_ERROR("TX shift register empty while transmiting data!");
-> error_detected;
end
end
end
join
end
 
 
// UART receiver monitor
//######################
 
// RX FIFO status
always@(rx_fifo_wr_pointer or rx_fifo_rd_pointer)
begin
if (rx_fifo_wr_pointer >= rx_fifo_rd_pointer)
rx_fifo_status = rx_fifo_wr_pointer - rx_fifo_rd_pointer;
else
rx_fifo_status = (5'h1F - rx_fifo_rd_pointer) + rx_fifo_wr_pointer;
end
// RX FIFO and RX data
initial
begin
rx_parity_err = 0;
rx_framing_err = 0;
rx_framing_glitch = 0;
rx_break_int = 0;
rx_overrun_err_occured = 0;
rx_fifo_par = 0;
rx_fifo_frm = 0;
rx_fifo_brk = 0;
rx_shift_reg_full = 0;
rx_fifo_wr_pointer = 0;
rx_fifo_rd_pointer = 0;
rx_fifo_status = 0;
fork
begin:write_rx_shift_reg
forever
begin
@(testbench.i_uart_device.device_sent_packet);
repeat (1) @(posedge wb_clk);
rx_shift_reg = testbench.i_uart_device.sent_data;
rx_parity_err = testbench.i_uart_device.tx_parity_enabled &&
(testbench.i_uart_device.tx_parity_wrong ||
( // sample point is BIT_NUM * 2 - 1 => 3, 5, 7...
((testbench.i_uart_device.tx_glitch_num == (3 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (5 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (7 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (9 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (11 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (13 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (15 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (17 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (19 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (21 * 8 * testbench.i_uart_device.T_divisor)) ||
(testbench.i_uart_device.tx_glitch_num == (23 * 8 * testbench.i_uart_device.T_divisor))) &&
(testbench.i_uart_device.tx_glitch_num[23:0] < ((testbench.i_uart_device.tx_length + 2'h1) *
16 * testbench.i_uart_device.T_divisor))
));
rx_framing_err = testbench.i_uart_device.tx_framing_wrong;
rx_framing_glitch = (testbench.i_uart_device.tx_glitch_num == ((((testbench.i_uart_device.tx_length + 2'h2 +
testbench.i_uart_device.tx_parity_enabled) *
2) - 1'b1) * 8 * testbench.i_uart_device.T_divisor));
rx_break_int = testbench.i_uart_device.tx_break_enable &&
(testbench.i_uart_device.tx_break_num[15:0] >= ((testbench.i_uart_device.tx_length + 2'h2 +
testbench.i_uart_device.tx_parity_enabled) *
16 * testbench.i_uart_device.T_divisor));
-> testbench.i_uart_device.sent_packet_received;
if (rx_fifo_status > 5'h0F)
rx_overrun_err_occured = 1'b1;
rx_shift_reg_full = 1'b1;
end
end
begin:write_rx_fifo_read_rx_shift_reg
forever
begin
wait (rx_shift_reg_full);
if (rx_fifo_status <= 5'h0F)
begin
rx_fifo_data[rx_fifo_wr_pointer] = testbench.i_uart_device.sent_data;
rx_fifo_par[rx_fifo_wr_pointer] = rx_parity_err;
rx_fifo_frm[rx_fifo_wr_pointer] = rx_framing_err || rx_framing_glitch;
rx_fifo_brk[rx_fifo_wr_pointer] = rx_break_int;
rx_fifo_wr_pointer = rx_fifo_wr_pointer + 1'b1;
end
else // FIFO overflow
begin
`BENCH_WARNING("RX FIFO overflow!");
end
repeat (1) @(posedge wb_clk);
rx_shift_reg_full = 0;
end
end
begin:empty_rx_fifo
forever
begin
wait (fcr_reg[1]);
rx_fifo_wr_pointer = 0;
rx_fifo_rd_pointer = 0;
// rx_fifo_par = 0;
// rx_fifo_frm = 0;
// rx_fifo_brk = 0;
@(posedge wb_clk);
if (rx_fifo_status == 0)
begin
`BENCH_MSG("RX FIFO is empty!");
end
end
end
begin:read_rx_fifo
rx_fifo_read = 0;
forever
begin
@(rx_reg_read);
if (rx_fifo_status > 0)
begin
rx_fifo_read = 1'b1;
// Check data
if (rx_fifo_data[rx_fifo_rd_pointer] != reg_dat)
begin
`BENCH_ERROR("RX data has ERROR!");
-> error_detected;
end
else
begin
`BENCH_MSG("RX data correct!");
end
// Set RX FIFO read pointer
repeat (1) @(posedge wb_clk);
rx_fifo_read = 0;
rx_fifo_rd_pointer = rx_fifo_rd_pointer + 1'b1;
end
else
begin
`BENCH_WARNING("Reading RX FIFO while RX FIFO is empty!");
end
 
 
if ((~rx_fifo_frm[rx_fifo_rd_pointer] && lsr_reg[3]) ||
(rx_fifo_frm[rx_fifo_rd_pointer] && ~lsr_reg[3]))
begin
`BENCH_ERROR("RX data has wrong framing ERROR!");
-> error_detected;
end
else
`BENCH_MSG("RX data has correct framing error!");
// Set RX FIFO read pointer
repeat (1) @(posedge wb_clk);
rx_fifo_read = 0;
if (rx_fifo_status > 0)
begin
// rx_fifo_par[rx_fifo_rd_pointer] = 1'b0;
// rx_fifo_frm[rx_fifo_rd_pointer] = 1'b0;
// rx_fifo_brk[rx_fifo_rd_pointer] = 1'b0;
rx_fifo_rd_pointer = rx_fifo_rd_pointer + 1'b1;
end
end
end
join
end
 
 
// UART interrupt monitor
//#######################
 
 
 
 
endmodule
 
 

powered by: WebSVN 2.1.0

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