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 101 to Rev 102
    Reverse comparison

Rev 101 → Rev 102

/tags/rel_3/rtl/verilog/uart_wb.v
0,0 → 1,317
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_wb.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core WISHBONE interface. ////
//// ////
//// Known problems (limits): ////
//// Inserts one wait state on all transfers. ////
//// Note affected signals and the way they are affected. ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.16 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.15 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.12 2001/12/19 08:03:34 mohor
// Warnings cleared.
//
// Revision 1.11 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.10 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.9 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.8 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.7 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/21 19:12:01 gorban
// Corrected some Linter messages.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:13+02 jacob
// Initial revision
//
//
 
// UART core WISHBONE interface
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "uart_defines.v"
module uart_wb (clk, wb_rst_i,
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_adr_i,
wb_adr_int, wb_dat_i, wb_dat_o, wb_dat8_i, wb_dat8_o, wb_dat32_o, wb_sel_i,
we_o, re_o // Write and read enable output for the core
);
 
input clk;
 
// WISHBONE interface
input wb_rst_i;
input wb_we_i;
input wb_stb_i;
input wb_cyc_i;
input [3:0] wb_sel_i;
input [`UART_ADDR_WIDTH-1:0] wb_adr_i; //WISHBONE address line
 
`ifdef DATA_BUS_WIDTH_8
input [7:0] wb_dat_i; //input WISHBONE bus
output [7:0] wb_dat_o;
reg [7:0] wb_dat_o;
wire [7:0] wb_dat_i;
reg [7:0] wb_dat_is;
`else // for 32 data bus mode
input [31:0] wb_dat_i; //input WISHBONE bus
output [31:0] wb_dat_o;
reg [31:0] wb_dat_o;
wire [31:0] wb_dat_i;
reg [31:0] wb_dat_is;
`endif // !`ifdef DATA_BUS_WIDTH_8
 
output [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
input [7:0] wb_dat8_o; // internal 8 bit output to be put into wb_dat_o
output [7:0] wb_dat8_i;
input [31:0] wb_dat32_o; // 32 bit data output (for debug interface)
output wb_ack_o;
output we_o;
output re_o;
 
wire we_o;
reg wb_ack_o;
reg [7:0] wb_dat8_i;
wire [7:0] wb_dat8_o;
wire [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
reg [`UART_ADDR_WIDTH-1:0] wb_adr_is;
reg wb_we_is;
reg wb_cyc_is;
reg wb_stb_is;
reg [3:0] wb_sel_is;
wire [3:0] wb_sel_i;
reg wre ;// timing control signal for write or read enable
 
// wb_ack_o FSM
reg [1:0] wbstate;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) begin
wb_ack_o <= #1 1'b0;
wbstate <= #1 0;
wre <= #1 1'b1;
end else
case (wbstate)
0: begin
if (wb_stb_is & wb_cyc_is) begin
wre <= #1 0;
wbstate <= #1 1;
wb_ack_o <= #1 1;
end else begin
wre <= #1 1;
wb_ack_o <= #1 0;
end
end
1: begin
wb_ack_o <= #1 0;
wbstate <= #1 2;
wre <= #1 0;
end
2,3: begin
wb_ack_o <= #1 0;
wbstate <= #1 0;
wre <= #1 0;
end
endcase
 
assign we_o = wb_we_is & wb_stb_is & wb_cyc_is & wre ; //WE for registers
assign re_o = ~wb_we_is & wb_stb_is & wb_cyc_is & wre ; //RE for registers
 
// Sample input signals
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) begin
wb_adr_is <= #1 0;
wb_we_is <= #1 0;
wb_cyc_is <= #1 0;
wb_stb_is <= #1 0;
wb_dat_is <= #1 0;
wb_sel_is <= #1 0;
end else begin
wb_adr_is <= #1 wb_adr_i;
wb_we_is <= #1 wb_we_i;
wb_cyc_is <= #1 wb_cyc_i;
wb_stb_is <= #1 wb_stb_i;
wb_dat_is <= #1 wb_dat_i;
wb_sel_is <= #1 wb_sel_i;
end
 
`ifdef DATA_BUS_WIDTH_8 // 8-bit data bus
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
wb_dat_o <= #1 0;
else
wb_dat_o <= #1 wb_dat8_o;
 
always @(wb_dat_is)
wb_dat8_i = wb_dat_is;
 
assign wb_adr_int = wb_adr_is;
 
`else // 32-bit bus
// put output to the correct byte in 32 bits using select line
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
wb_dat_o <= #1 0;
else if (re_o)
case (wb_sel_is)
4'b0001: wb_dat_o <= #1 {24'b0, wb_dat8_o};
4'b0010: wb_dat_o <= #1 {16'b0, wb_dat8_o, 8'b0};
4'b0100: wb_dat_o <= #1 {8'b0, wb_dat8_o, 16'b0};
4'b1000: wb_dat_o <= #1 {wb_dat8_o, 24'b0};
4'b1111: wb_dat_o <= #1 wb_dat32_o; // debug interface output
default: wb_dat_o <= #1 0;
endcase // case(wb_sel_i)
 
reg [1:0] wb_adr_int_lsb;
 
always @(wb_sel_is or wb_dat_is)
begin
case (wb_sel_is)
4'b0001 : wb_dat8_i = wb_dat_is[7:0];
4'b0010 : wb_dat8_i = wb_dat_is[15:8];
4'b0100 : wb_dat8_i = wb_dat_is[23:16];
4'b1000 : wb_dat8_i = wb_dat_is[31:24];
default : wb_dat8_i = wb_dat_is[7:0];
endcase // case(wb_sel_i)
 
`ifdef LITLE_ENDIAN
case (wb_sel_is)
4'b0001 : wb_adr_int_lsb = 2'h0;
4'b0010 : wb_adr_int_lsb = 2'h1;
4'b0100 : wb_adr_int_lsb = 2'h2;
4'b1000 : wb_adr_int_lsb = 2'h3;
default : wb_adr_int_lsb = 2'h0;
endcase // case(wb_sel_i)
`else
case (wb_sel_is)
4'b0001 : wb_adr_int_lsb = 2'h3;
4'b0010 : wb_adr_int_lsb = 2'h2;
4'b0100 : wb_adr_int_lsb = 2'h1;
4'b1000 : wb_adr_int_lsb = 2'h0;
default : wb_adr_int_lsb = 2'h0;
endcase // case(wb_sel_i)
`endif
end
 
assign wb_adr_int = {wb_adr_is[`UART_ADDR_WIDTH-1:2], wb_adr_int_lsb};
 
`endif // !`ifdef DATA_BUS_WIDTH_8
 
endmodule
 
 
 
 
 
 
 
 
 
 
/tags/rel_3/rtl/verilog/uart_receiver.v
0,0 → 1,482
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_receiver.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core receiver logic ////
//// ////
//// Known problems (limits): ////
//// None known ////
//// ////
//// To Do: ////
//// Thourough testing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.29 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.28 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.27 2001/12/30 20:39:13 mohor
// More than one character was stored in case of break. End of the break
// was not detected correctly.
//
// Revision 1.26 2001/12/20 13:28:27 mohor
// Missing declaration of rf_push_q fixed.
//
// Revision 1.25 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.24 2001/12/19 08:03:34 mohor
// Warnings cleared.
//
// Revision 1.23 2001/12/19 07:33:54 mohor
// Synplicity was having troubles with the comment.
//
// Revision 1.22 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.21 2001/12/13 10:31:16 mohor
// timeout irq must be set regardless of the rda irq (rda irq does not reset the
// timeout counter).
//
// Revision 1.20 2001/12/10 19:52:05 gorban
// Igor fixed break condition bugs
//
// Revision 1.19 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.18 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.17 2001/11/28 19:36:39 gorban
// Fixed: timeout and break didn't pay attention to current data format when counting time
//
// Revision 1.16 2001/11/27 22:17:09 gorban
// Fixed bug that prevented synthesis in uart_receiver.v
//
// Revision 1.15 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.14 2001/11/10 12:43:21 gorban
// Logic Synthesis bugs fixed. Some other minor changes
//
// Revision 1.13 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.12 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.11 2001/10/31 15:19:22 gorban
// Fixes to break and timeout conditions
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.6 2001/06/23 11:21:48 gorban
// DL made 16-bit long. Fixed transmission/reception bugs.
//
// Revision 1.5 2001/06/02 14:28:14 gorban
// Fixed receiver and transmitter. Major bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:49 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.1 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable,
counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
 
input clk;
input wb_rst_i;
input [7:0] lcr;
input rf_pop;
input srx_pad_i;
input enable;
input rx_reset;
input lsr_mask;
 
output [9:0] counter_t;
output [`UART_FIFO_COUNTER_W-1:0] rf_count;
output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
output rf_overrun;
output rf_error_bit;
output [3:0] rstate;
output rf_push_pulse;
 
reg [3:0] rstate;
reg [3:0] rcounter16;
reg [2:0] rbit_counter;
reg [7:0] rshift; // receiver shift register
reg rparity; // received parity
reg rparity_error;
reg rframing_error; // framing error flag
reg rbit_in;
reg rparity_xor;
reg [7:0] counter_b; // counts the 0 (low) signals
reg rf_push_q;
 
// RX FIFO signals
reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in;
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_push_pulse;
reg rf_push;
wire rf_pop;
wire rf_overrun;
wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
wire break_error = (counter_b == 0);
 
// RX FIFO instance
uart_rfifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
.clk( clk ),
.wb_rst_i( wb_rst_i ),
.data_in( rf_data_in ),
.data_out( rf_data_out ),
.push( rf_push_pulse ),
.pop( rf_pop ),
.overrun( rf_overrun ),
.count( rf_count ),
.error_bit( rf_error_bit ),
.fifo_reset( rx_reset ),
.reset_status(lsr_mask)
);
 
wire rcounter16_eq_7 = (rcounter16 == 4'd7);
wire rcounter16_eq_0 = (rcounter16 == 4'd0);
wire rcounter16_eq_1 = (rcounter16 == 4'd1);
 
wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
 
parameter sr_idle = 4'd0;
parameter sr_rec_start = 4'd1;
parameter sr_rec_bit = 4'd2;
parameter sr_rec_parity = 4'd3;
parameter sr_rec_stop = 4'd4;
parameter sr_check_parity = 4'd5;
parameter sr_rec_prepare = 4'd6;
parameter sr_end_bit = 4'd7;
parameter sr_ca_lc_parity = 4'd8;
parameter sr_wait1 = 4'd9;
parameter sr_push = 4'd10;
 
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
rstate <= #1 sr_idle;
rbit_in <= #1 1'b0;
rcounter16 <= #1 0;
rbit_counter <= #1 0;
rparity_xor <= #1 1'b0;
rframing_error <= #1 1'b0;
rparity_error <= #1 1'b0;
rparity <= #1 1'b0;
rshift <= #1 0;
rf_push <= #1 1'b0;
rf_data_in <= #1 0;
end
else
if (enable)
begin
case (rstate)
sr_idle : begin
rf_push <= #1 1'b0;
rf_data_in <= #1 0;
rcounter16 <= #1 4'b1110;
if (srx_pad_i==1'b0 & ~break_error) // detected a pulse (start bit?)
begin
rstate <= #1 sr_rec_start;
end
end
sr_rec_start : begin
rf_push <= #1 1'b0;
if (rcounter16_eq_7) // check the pulse
if (srx_pad_i==1'b1) // no start bit
rstate <= #1 sr_idle;
else // start bit detected
rstate <= #1 sr_rec_prepare;
rcounter16 <= #1 rcounter16_minus_1;
end
sr_rec_prepare:begin
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
2'b00 : rbit_counter <= #1 3'b100;
2'b01 : rbit_counter <= #1 3'b101;
2'b10 : rbit_counter <= #1 3'b110;
2'b11 : rbit_counter <= #1 3'b111;
endcase
if (rcounter16_eq_0)
begin
rstate <= #1 sr_rec_bit;
rcounter16 <= #1 4'b1110;
rshift <= #1 0;
end
else
rstate <= #1 sr_rec_prepare;
rcounter16 <= #1 rcounter16_minus_1;
end
sr_rec_bit : begin
if (rcounter16_eq_0)
rstate <= #1 sr_end_bit;
if (rcounter16_eq_7) // read the bit
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
2'b00 : rshift[4:0] <= #1 {srx_pad_i, rshift[4:1]};
2'b01 : rshift[5:0] <= #1 {srx_pad_i, rshift[5:1]};
2'b10 : rshift[6:0] <= #1 {srx_pad_i, rshift[6:1]};
2'b11 : rshift[7:0] <= #1 {srx_pad_i, rshift[7:1]};
endcase
rcounter16 <= #1 rcounter16_minus_1;
end
sr_end_bit : begin
if (rbit_counter==3'b0) // no more bits in word
if (lcr[`UART_LC_PE]) // choose state based on parity
rstate <= #1 sr_rec_parity;
else
begin
rstate <= #1 sr_rec_stop;
rparity_error <= #1 1'b0; // no parity - no error :)
end
else // else we have more bits to read
begin
rstate <= #1 sr_rec_bit;
rbit_counter <= #1 rbit_counter - 1'b1;
end
rcounter16 <= #1 4'b1110;
end
sr_rec_parity: begin
if (rcounter16_eq_7) // read the parity
begin
rparity <= #1 srx_pad_i;
rstate <= #1 sr_ca_lc_parity;
end
rcounter16 <= #1 rcounter16_minus_1;
end
sr_ca_lc_parity : begin // rcounter equals 6
rcounter16 <= #1 rcounter16_minus_1;
rparity_xor <= #1 ^{rshift,rparity}; // calculate parity on all incoming data
rstate <= #1 sr_check_parity;
end
sr_check_parity: begin // rcounter equals 5
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
2'b00: rparity_error <= #1 rparity_xor == 0; // no error if parity 1
2'b01: rparity_error <= #1 ~rparity; // parity should sticked to 1
2'b10: rparity_error <= #1 rparity_xor == 1; // error if parity is odd
2'b11: rparity_error <= #1 rparity; // parity should be sticked to 0
endcase
rcounter16 <= #1 rcounter16_minus_1;
rstate <= #1 sr_wait1;
end
sr_wait1 : if (rcounter16_eq_0)
begin
rstate <= #1 sr_rec_stop;
rcounter16 <= #1 4'b1110;
end
else
rcounter16 <= #1 rcounter16_minus_1;
sr_rec_stop : begin
if (rcounter16_eq_7) // read the parity
begin
rframing_error <= #1 !srx_pad_i; // no framing error if input is 1 (stop bit)
rstate <= #1 sr_push;
end
rcounter16 <= #1 rcounter16_minus_1;
end
sr_push : begin
///////////////////////////////////////
// $display($time, ": received: %b", rf_data_in);
if(srx_pad_i | break_error)
begin
if(break_error)
rf_data_in <= #1 {8'b0, 3'b100}; // break input (empty character) to receiver FIFO
else
rf_data_in <= #1 {rshift, 1'b0, rparity_error, rframing_error};
rf_push <= #1 1'b1;
rstate <= #1 sr_idle;
end
else
begin
rf_data_in <= #1 {rshift, 1'b0, rparity_error, rframing_error};
rf_push <= #1 1'b1;
rcounter16 <= #1 4'b1110;
rstate <= #1 sr_rec_start;
end
end
default : rstate <= #1 sr_idle;
endcase
end // if (enable)
end // always of receiver
 
always @ (posedge clk or posedge wb_rst_i)
begin
if(wb_rst_i)
rf_push_q <= 0;
else
rf_push_q <= #1 rf_push;
end
 
assign rf_push_pulse = rf_push & ~rf_push_q;
 
//
// Break condition detection.
// Works in conjuction with the receiver state machine
 
reg [9:0] toc_value; // value to be set to timeout counter
 
always @(lcr)
case (lcr[3:0])
4'b0000 : toc_value = 447; // 7 bits
4'b0100 : toc_value = 479; // 7.5 bits
4'b0001, 4'b1000 : toc_value = 511; // 8 bits
4'b1100 : toc_value = 543; // 8.5 bits
4'b0010, 4'b0101, 4'b1001 : toc_value = 575; // 9 bits
4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639; // 10 bits
4'b0111, 4'b1011, 4'b1110 : toc_value = 703; // 11 bits
4'b1111 : toc_value = 767; // 12 bits
endcase // case(lcr[3:0])
 
wire [7:0] brc_value; // value to be set to break counter
assign brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
counter_b <= #1 8'd159;
else
if (srx_pad_i)
counter_b <= #1 brc_value; // character time length - 1
else
if(enable & counter_b != 8'b0) // only work on enable times break not reached.
counter_b <= #1 counter_b - 1; // decrement break counter
end // always of break condition detection
 
///
/// Timeout condition detection
reg [9:0] counter_t; // counts the timeout condition clocks
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
counter_t <= #1 10'd639; // 10 bits for the default 8N1
else
if(rf_push_pulse || rf_pop || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level
counter_t <= #1 toc_value;
else
if (enable && counter_t != 10'b0) // we don't want to underflow
counter_t <= #1 counter_t - 1;
end
endmodule
/tags/rel_3/rtl/verilog/uart_regs.v
0,0 → 1,890
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_regs.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Registers of the uart 16550 core ////
//// ////
//// Known problems (limits): ////
//// Inserts 1 wait state in all WISHBONE transfers ////
//// ////
//// To Do: ////
//// Nothing or verification. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: (See log for the revision history ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.40 2003/06/11 16:37:47 gorban
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
//
// Revision 1.39 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.38 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.37 2001/12/27 13:24:09 mohor
// lsr[7] was not showing overrun errors.
//
// Revision 1.36 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.35 2001/12/19 08:03:34 mohor
// Warnings cleared.
//
// Revision 1.34 2001/12/19 07:33:54 mohor
// Synplicity was having troubles with the comment.
//
// Revision 1.33 2001/12/17 10:14:43 mohor
// Things related to msr register changed. After THRE IRQ occurs, and one
// character is written to the transmit fifo, the detection of the THRE bit in the
// LSR is delayed for one character time.
//
// Revision 1.32 2001/12/14 13:19:24 mohor
// MSR register fixed.
//
// Revision 1.31 2001/12/14 10:06:58 mohor
// After reset modem status register MSR should be reset.
//
// Revision 1.30 2001/12/13 10:09:13 mohor
// thre irq should be cleared only when being source of interrupt.
//
// Revision 1.29 2001/12/12 09:05:46 mohor
// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
//
// Revision 1.28 2001/12/10 19:52:41 gorban
// Scratch register added
//
// Revision 1.27 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.26 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.25 2001/11/28 19:36:39 gorban
// Fixed: timeout and break didn't pay attention to current data format when counting time
//
// Revision 1.24 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.23 2001/11/12 21:57:29 gorban
// fixed more typo bugs
//
// Revision 1.22 2001/11/12 15:02:28 mohor
// lsr1r error fixed.
//
// Revision 1.21 2001/11/12 14:57:27 mohor
// ti_int_pnd error fixed.
//
// Revision 1.20 2001/11/12 14:50:27 mohor
// ti_int_d error fixed.
//
// Revision 1.19 2001/11/10 12:43:21 gorban
// Logic Synthesis bugs fixed. Some other minor changes
//
// Revision 1.18 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.17 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.16 2001/11/02 09:55:16 mohor
// no message
//
// Revision 1.15 2001/10/31 15:19:22 gorban
// Fixes to break and timeout conditions
//
// Revision 1.14 2001/10/29 17:00:46 gorban
// fixed parity sending and tx_fifo resets over- and underrun
//
// Revision 1.13 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.12 2001/10/19 16:21:40 gorban
// Changes data_out to be synchronous again as it should have been.
//
// Revision 1.11 2001/10/18 20:35:45 gorban
// small fix
//
// Revision 1.10 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.9 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.10 2001/06/23 11:21:48 gorban
// DL made 16-bit long. Fixed transmission/reception bugs.
//
// Revision 1.9 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.8 2001/05/29 20:05:04 gorban
// Fixed some bugs and synthesis problems.
//
// Revision 1.7 2001/05/27 17:37:49 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.6 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.5 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
`define UART_DL1 7:0
`define UART_DL2 15:8
 
module uart_regs (clk,
wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
 
// additional signals
modem_inputs,
stx_pad_o, srx_pad_i,
 
`ifdef DATA_BUS_WIDTH_8
`else
// debug interface signals enabled
ier, iir, fcr, mcr, lcr, msr, lsr, rf_count, tf_count, tstate, rstate,
`endif
rts_pad_o, dtr_pad_o, int_o
`ifdef UART_HAS_BAUDRATE_OUTPUT
, baud_o
`endif
 
);
 
input clk;
input wb_rst_i;
input [`UART_ADDR_WIDTH-1:0] wb_addr_i;
input [7:0] wb_dat_i;
output [7:0] wb_dat_o;
input wb_we_i;
input wb_re_i;
 
output stx_pad_o;
input srx_pad_i;
 
input [3:0] modem_inputs;
output rts_pad_o;
output dtr_pad_o;
output int_o;
`ifdef UART_HAS_BAUDRATE_OUTPUT
output baud_o;
`endif
 
`ifdef DATA_BUS_WIDTH_8
`else
// if 32-bit databus and debug interface are enabled
output [3:0] ier;
output [3:0] iir;
output [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
output [4:0] mcr;
output [7:0] lcr;
output [7:0] msr;
output [7:0] lsr;
output [`UART_FIFO_COUNTER_W-1:0] rf_count;
output [`UART_FIFO_COUNTER_W-1:0] tf_count;
output [2:0] tstate;
output [3:0] rstate;
 
`endif
 
wire [3:0] modem_inputs;
reg enable;
`ifdef UART_HAS_BAUDRATE_OUTPUT
assign baud_o = enable; // baud_o is actually the enable signal
`endif
 
 
wire stx_pad_o; // received from transmitter module
wire srx_pad_i;
wire srx_pad;
 
reg [7:0] wb_dat_o;
 
wire [`UART_ADDR_WIDTH-1:0] wb_addr_i;
wire [7:0] wb_dat_i;
 
 
reg [3:0] ier;
reg [3:0] iir;
reg [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
reg [4:0] mcr;
reg [7:0] lcr;
reg [7:0] msr;
reg [15:0] dl; // 32-bit divisor latch
reg [7:0] scratch; // UART scratch register
reg start_dlc; // activate dlc on writing to UART_DL1
reg lsr_mask_d; // delay for lsr_mask condition
reg msi_reset; // reset MSR 4 lower bits indicator
//reg threi_clear; // THRE interrupt clear flag
reg [15:0] dlc; // 32-bit divisor latch counter
reg int_o;
 
reg [3:0] trigger_level; // trigger level of the receiver FIFO
reg rx_reset;
reg tx_reset;
 
wire dlab; // divisor latch access bit
wire cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
wire loopback; // loopback bit (MCR bit 4)
wire cts, dsr, ri, dcd; // effective signals
wire cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
wire rts_pad_o, dtr_pad_o; // modem control outputs
 
// LSR bits wires and regs
wire [7:0] lsr;
wire lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
reg lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
wire lsr_mask; // lsr_mask
 
//
// ASSINGS
//
 
assign lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
 
assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
assign {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
 
assign {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
: {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
 
assign dlab = lcr[`UART_LC_DL];
assign loopback = mcr[4];
 
// assign modem outputs
assign rts_pad_o = mcr[`UART_MC_RTS];
assign dtr_pad_o = mcr[`UART_MC_DTR];
 
// Interrupt signals
wire rls_int; // receiver line status interrupt
wire rda_int; // receiver data available interrupt
wire ti_int; // timeout indicator interrupt
wire thre_int; // transmitter holding register empty interrupt
wire ms_int; // modem status interrupt
 
// FIFO signals
reg tf_push;
reg rf_pop;
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
wire [2:0] tstate;
wire [3:0] rstate;
wire [9:0] counter_t;
 
wire thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
reg [7:0] block_cnt; // While counter counts, THRE status is blocked (delayed one character cycle)
reg [7:0] block_value; // One character length minus stop bit
 
// Transmitter Instance
wire serial_out;
 
uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
 
// Synchronizing and sampling serial RX input
uart_sync_flops i_uart_sync_flops
(
.rst_i (wb_rst_i),
.clk_i (clk),
.stage1_rst_i (1'b0),
.stage1_clk_en_i (1'b1),
.async_dat_i (srx_pad_i),
.sync_dat_o (srx_pad)
);
defparam i_uart_sync_flops.width = 1;
defparam i_uart_sync_flops.init_value = 1'b1;
 
// handle loopback
wire serial_in = loopback ? serial_out : srx_pad;
assign stx_pad_o = loopback ? 1'b1 : serial_out;
 
// Receiver Instance
uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
 
 
// Asynchronous reading here because the outputs are sampled in uart_wb.v file
always @(dl or dlab or ier or iir or scratch
or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) // asynchrounous reading
begin
case (wb_addr_i)
`UART_REG_RB : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
`UART_REG_IE : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
`UART_REG_II : wb_dat_o = {4'b1100,iir};
`UART_REG_LC : wb_dat_o = lcr;
`UART_REG_LS : wb_dat_o = lsr;
`UART_REG_MS : wb_dat_o = msr;
`UART_REG_SR : wb_dat_o = scratch;
default: wb_dat_o = 8'b0; // ??
endcase // case(wb_addr_i)
end // always @ (dl or dlab or ier or iir or scratch...
 
 
// rf_pop signal handling
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
rf_pop <= #1 0;
else
if (rf_pop) // restore the signal to 0 after one clock cycle
rf_pop <= #1 0;
else
if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
rf_pop <= #1 1; // advance read pointer
end
 
wire lsr_mask_condition;
wire iir_read;
wire msr_read;
wire fifo_read;
wire fifo_write;
 
assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
 
// lsr_mask_d delayed signal handling
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
lsr_mask_d <= #1 0;
else // reset bits in the Line Status Register
lsr_mask_d <= #1 lsr_mask_condition;
end
 
// lsr_mask is rise detected
assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
 
// msi_reset signal handling
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
msi_reset <= #1 1;
else
if (msi_reset)
msi_reset <= #1 0;
else
if (msr_read)
msi_reset <= #1 1; // reset bits in Modem Status Register
end
 
 
//
// WRITES AND RESETS //
//
// Line Control Register
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
lcr <= #1 8'b00000011; // 8n1 setting
else
if (wb_we_i && wb_addr_i==`UART_REG_LC)
lcr <= #1 wb_dat_i;
 
// Interrupt Enable Register or UART_DL2
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
begin
ier <= #1 4'b0000; // no interrupts after reset
dl[`UART_DL2] <= #1 8'b0;
end
else
if (wb_we_i && wb_addr_i==`UART_REG_IE)
if (dlab)
begin
dl[`UART_DL2] <= #1 wb_dat_i;
end
else
ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb
 
 
// FIFO Control Register and rx_reset, tx_reset signals
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) begin
fcr <= #1 2'b11;
rx_reset <= #1 0;
tx_reset <= #1 0;
end else
if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
fcr <= #1 wb_dat_i[7:6];
rx_reset <= #1 wb_dat_i[1];
tx_reset <= #1 wb_dat_i[2];
end else begin
rx_reset <= #1 0;
tx_reset <= #1 0;
end
 
// Modem Control Register
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
mcr <= #1 5'b0;
else
if (wb_we_i && wb_addr_i==`UART_REG_MC)
mcr <= #1 wb_dat_i[4:0];
 
// Scratch register
// Line Control Register
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
scratch <= #1 0; // 8n1 setting
else
if (wb_we_i && wb_addr_i==`UART_REG_SR)
scratch <= #1 wb_dat_i;
 
// TX_FIFO or UART_DL1
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
begin
dl[`UART_DL1] <= #1 8'b0;
tf_push <= #1 1'b0;
start_dlc <= #1 1'b0;
end
else
if (wb_we_i && wb_addr_i==`UART_REG_TR)
if (dlab)
begin
dl[`UART_DL1] <= #1 wb_dat_i;
start_dlc <= #1 1'b1; // enable DL counter
tf_push <= #1 1'b0;
end
else
begin
tf_push <= #1 1'b1;
start_dlc <= #1 1'b0;
end // else: !if(dlab)
else
begin
start_dlc <= #1 1'b0;
tf_push <= #1 1'b0;
end // else: !if(dlab)
 
// Receiver FIFO trigger level selection logic (asynchronous mux)
always @(fcr)
case (fcr[`UART_FC_TL])
2'b00 : trigger_level = 1;
2'b01 : trigger_level = 4;
2'b10 : trigger_level = 8;
2'b11 : trigger_level = 14;
endcase // case(fcr[`UART_FC_TL])
//
// STATUS REGISTERS //
//
 
// Modem Status Register
reg [3:0] delayed_modem_signals;
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
msr <= #1 0;
delayed_modem_signals[3:0] <= #1 0;
end
else begin
msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 :
msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
msr[`UART_MS_CDCD:`UART_MS_CCTS] <= #1 {dcd_c, ri_c, dsr_c, cts_c};
delayed_modem_signals[3:0] <= #1 {dcd, ri, dsr, cts};
end
end
 
 
// Line Status Register
 
// activation conditions
assign lsr0 = (rf_count==0 && rf_push_pulse); // data in receiver fifo available set condition
assign lsr1 = rf_overrun; // Receiver overrun error
assign lsr2 = rf_data_out[1]; // parity error bit
assign lsr3 = rf_data_out[0]; // framing error bit
assign lsr4 = rf_data_out[2]; // break error in the character
assign lsr5 = (tf_count==5'b0 && thre_set_en); // transmitter fifo is empty
assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
assign lsr7 = rf_error_bit | rf_overrun;
 
// lsr bit0 (receiver data available)
reg lsr0_d;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr0_d <= #1 0;
else lsr0_d <= #1 lsr0;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr0r <= #1 0;
else lsr0r <= #1 (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
 
// lsr bit 1 (receiver overrun)
reg lsr1_d; // delayed
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr1_d <= #1 0;
else lsr1_d <= #1 lsr1;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr1r <= #1 0;
else lsr1r <= #1 lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
 
// lsr bit 2 (parity error)
reg lsr2_d; // delayed
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr2_d <= #1 0;
else lsr2_d <= #1 lsr2;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr2r <= #1 0;
else lsr2r <= #1 lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
 
// lsr bit 3 (framing error)
reg lsr3_d; // delayed
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr3_d <= #1 0;
else lsr3_d <= #1 lsr3;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr3r <= #1 0;
else lsr3r <= #1 lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
 
// lsr bit 4 (break indicator)
reg lsr4_d; // delayed
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr4_d <= #1 0;
else lsr4_d <= #1 lsr4;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr4r <= #1 0;
else lsr4r <= #1 lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
 
// lsr bit 5 (transmitter fifo is empty)
reg lsr5_d;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr5_d <= #1 1;
else lsr5_d <= #1 lsr5;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr5r <= #1 1;
else lsr5r <= #1 (fifo_write) ? 0 : lsr5r || (lsr5 && ~lsr5_d);
 
// lsr bit 6 (transmitter empty indicator)
reg lsr6_d;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr6_d <= #1 1;
else lsr6_d <= #1 lsr6;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr6r <= #1 1;
else lsr6r <= #1 (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
 
// lsr bit 7 (error in fifo)
reg lsr7_d;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr7_d <= #1 0;
else lsr7_d <= #1 lsr7;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr7r <= #1 0;
else lsr7r <= #1 lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
 
// Frequency divider
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
dlc <= #1 0;
else
if (start_dlc | ~ (|dlc))
dlc <= #1 dl - 1; // preset counter
else
dlc <= #1 dlc - 1; // decrement counter
end
 
// Enable signal generation logic
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
enable <= #1 1'b0;
else
if (|dl & ~(|dlc)) // dl>0 & dlc==0
enable <= #1 1'b1;
else
enable <= #1 1'b0;
end
 
// Delaying THRE status for one character cycle after a character is written to an empty fifo.
always @(lcr)
case (lcr[3:0])
4'b0000 : block_value = 95; // 6 bits
4'b0100 : block_value = 103; // 6.5 bits
4'b0001, 4'b1000 : block_value = 111; // 7 bits
4'b1100 : block_value = 119; // 7.5 bits
4'b0010, 4'b0101, 4'b1001 : block_value = 127; // 8 bits
4'b0011, 4'b0110, 4'b1010, 4'b1101 : block_value = 143; // 9 bits
4'b0111, 4'b1011, 4'b1110 : block_value = 159; // 10 bits
4'b1111 : block_value = 175; // 11 bits
endcase // case(lcr[3:0])
 
// Counting time of one character minus stop bit
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
block_cnt <= #1 8'd0;
else
if(lsr5r & fifo_write) // THRE bit set & write to fifo occured
block_cnt <= #1 block_value;
else
if (enable & block_cnt != 8'b0) // only work on enable times
block_cnt <= #1 block_cnt - 1; // decrement break counter
end // always of break condition detection
 
// Generating THRE status enable signal
assign thre_set_en = ~(|block_cnt);
 
 
//
// INTERRUPT LOGIC
//
 
assign rls_int = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
assign rda_int = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
assign ms_int = ier[`UART_IE_MS] && (| msr[3:0]);
assign ti_int = ier[`UART_IE_RDA] && (counter_t == 10'b0);
 
reg rls_int_d;
reg thre_int_d;
reg ms_int_d;
reg ti_int_d;
reg rda_int_d;
 
// delay lines
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rls_int_d <= #1 0;
else rls_int_d <= #1 rls_int;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rda_int_d <= #1 0;
else rda_int_d <= #1 rda_int;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) thre_int_d <= #1 0;
else thre_int_d <= #1 thre_int;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ms_int_d <= #1 0;
else ms_int_d <= #1 ms_int;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ti_int_d <= #1 0;
else ti_int_d <= #1 ti_int;
 
// rise detection signals
 
wire rls_int_rise;
wire thre_int_rise;
wire ms_int_rise;
wire ti_int_rise;
wire rda_int_rise;
 
assign rda_int_rise = rda_int & ~rda_int_d;
assign rls_int_rise = rls_int & ~rls_int_d;
assign thre_int_rise = thre_int & ~thre_int_d;
assign ms_int_rise = ms_int & ~ms_int_d;
assign ti_int_rise = ti_int & ~ti_int_d;
 
// interrupt pending flags
reg rls_int_pnd;
reg rda_int_pnd;
reg thre_int_pnd;
reg ms_int_pnd;
reg ti_int_pnd;
 
// interrupt pending flags assignments
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rls_int_pnd <= #1 0;
else
rls_int_pnd <= #1 lsr_mask ? 0 : // reset condition
rls_int_rise ? 1 : // latch condition
rls_int_pnd && ier[`UART_IE_RLS]; // default operation: remove if masked
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rda_int_pnd <= #1 0;
else
rda_int_pnd <= #1 ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 : // reset condition
rda_int_rise ? 1 : // latch condition
rda_int_pnd && ier[`UART_IE_RDA]; // default operation: remove if masked
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) thre_int_pnd <= #1 0;
else
thre_int_pnd <= #1 fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
thre_int_rise ? 1 :
thre_int_pnd && ier[`UART_IE_THRE];
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ms_int_pnd <= #1 0;
else
ms_int_pnd <= #1 msr_read ? 0 :
ms_int_rise ? 1 :
ms_int_pnd && ier[`UART_IE_MS];
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ti_int_pnd <= #1 0;
else
ti_int_pnd <= #1 fifo_read ? 0 :
ti_int_rise ? 1 :
ti_int_pnd && ier[`UART_IE_RDA];
// end of pending flags
 
// INT_O logic
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
int_o <= #1 1'b0;
else
int_o <= #1
rls_int_pnd ? ~lsr_mask :
rda_int_pnd ? 1 :
ti_int_pnd ? ~fifo_read :
thre_int_pnd ? !(fifo_write & iir_read) :
ms_int_pnd ? ~msr_read :
0; // if no interrupt are pending
end
 
 
// Interrupt Identification register
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
iir <= #1 1;
else
if (rls_int_pnd) // interrupt is pending
begin
iir[`UART_II_II] <= #1 `UART_II_RLS; // set identification register to correct value
iir[`UART_II_IP] <= #1 1'b0; // and clear the IIR bit 0 (interrupt pending)
end else // the sequence of conditions determines priority of interrupt identification
if (rda_int)
begin
iir[`UART_II_II] <= #1 `UART_II_RDA;
iir[`UART_II_IP] <= #1 1'b0;
end
else if (ti_int_pnd)
begin
iir[`UART_II_II] <= #1 `UART_II_TI;
iir[`UART_II_IP] <= #1 1'b0;
end
else if (thre_int_pnd)
begin
iir[`UART_II_II] <= #1 `UART_II_THRE;
iir[`UART_II_IP] <= #1 1'b0;
end
else if (ms_int_pnd)
begin
iir[`UART_II_II] <= #1 `UART_II_MS;
iir[`UART_II_IP] <= #1 1'b0;
end else // no interrupt is pending
begin
iir[`UART_II_II] <= #1 0;
iir[`UART_II_IP] <= #1 1'b1;
end
end
 
endmodule
/tags/rel_3/rtl/verilog/uart_sync_flops.v
0,0 → 1,122
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_sync_flops.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core receiver logic ////
//// ////
//// Known problems (limits): ////
//// None known ////
//// ////
//// To Do: ////
//// Thourough testing. ////
//// ////
//// Author(s): ////
//// - Andrej Erzen (andreje@flextronics.si) ////
//// - Tadej Markovic (tadejm@flextronics.si) ////
//// ////
//// Created: 2004/05/20 ////
//// Last Updated: 2004/05/20 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 "timescale.v"
 
 
module uart_sync_flops
(
// internal signals
rst_i,
clk_i,
stage1_rst_i,
stage1_clk_en_i,
async_dat_i,
sync_dat_o
);
 
parameter Tp = 1;
parameter width = 1;
parameter init_value = 1'b0;
 
input rst_i; // reset input
input clk_i; // clock input
input stage1_rst_i; // synchronous reset for stage 1 FF
input stage1_clk_en_i; // synchronous clock enable for stage 1 FF
input [width-1:0] async_dat_i; // asynchronous data input
output [width-1:0] sync_dat_o; // synchronous data output
 
 
//
// Interal signal declarations
//
 
reg [width-1:0] sync_dat_o;
reg [width-1:0] flop_0;
 
 
// first stage
always @ (posedge clk_i or posedge rst_i)
begin
if (rst_i)
flop_0 <= #Tp {width{init_value}};
else
flop_0 <= #Tp async_dat_i;
end
 
// second stage
always @ (posedge clk_i or posedge rst_i)
begin
if (rst_i)
sync_dat_o <= #Tp {width{init_value}};
else if (stage1_rst_i)
sync_dat_o <= #Tp {width{init_value}};
else if (stage1_clk_en_i)
sync_dat_o <= #Tp flop_0;
end
 
endmodule
/tags/rel_3/rtl/verilog/uart_defines.v
0,0 → 1,247
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_defines.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Defines of the Core ////
//// ////
//// Known problems (limits): ////
//// None ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.13 2003/06/11 16:37:47 gorban
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
//
// Revision 1.12 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.10 2001/12/11 08:55:40 mohor
// Scratch register define added.
//
// Revision 1.9 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.8 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.7 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.6 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.5 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.4 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.3 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
//
 
// remove comments to restore to use the new version with 8 data bit interface
// in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place
// also, in 8-bit version there'll be no debugging features included
// CAUTION: doesn't work with current version of OR1200
//`define DATA_BUS_WIDTH_8
 
`ifdef DATA_BUS_WIDTH_8
`define UART_ADDR_WIDTH 3
`define UART_DATA_WIDTH 8
`else
`define UART_ADDR_WIDTH 5
`define UART_DATA_WIDTH 32
`endif
 
// Uncomment this if you want your UART to have
// 16xBaudrate output port.
// If defined, the enable signal will be used to drive baudrate_o signal
// It's frequency is 16xbaudrate
 
// `define UART_HAS_BAUDRATE_OUTPUT
 
// Register addresses
`define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer
`define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter
`define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable
`define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification
`define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control
`define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control
`define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control
`define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status
`define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status
`define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register
`define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2)
`define UART_REG_DL2 `UART_ADDR_WIDTH'd1
 
// Interrupt Enable register bits
`define UART_IE_RDA 0 // Received Data available interrupt
`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt
`define UART_IE_RLS 2 // Receiver Line Status Interrupt
`define UART_IE_MS 3 // Modem Status Interrupt
 
// Interrupt Identification register bits
`define UART_II_IP 0 // Interrupt pending when 0
`define UART_II_II 3:1 // Interrupt identification
 
// Interrupt identification values for bits 3:1
`define UART_II_RLS 3'b011 // Receiver Line Status
`define UART_II_RDA 3'b010 // Receiver Data available
`define UART_II_TI 3'b110 // Timeout Indication
`define UART_II_THRE 3'b001 // Transmitter Holding Register empty
`define UART_II_MS 3'b000 // Modem Status
 
// FIFO Control Register bits
`define UART_FC_TL 1:0 // Trigger level
 
// FIFO trigger level values
`define UART_FC_1 2'b00
`define UART_FC_4 2'b01
`define UART_FC_8 2'b10
`define UART_FC_14 2'b11
 
// Line Control register bits
`define UART_LC_BITS 1:0 // bits in character
`define UART_LC_SB 2 // stop bits
`define UART_LC_PE 3 // parity enable
`define UART_LC_EP 4 // even parity
`define UART_LC_SP 5 // stick parity
`define UART_LC_BC 6 // Break control
`define UART_LC_DL 7 // Divisor Latch access bit
 
// Modem Control register bits
`define UART_MC_DTR 0
`define UART_MC_RTS 1
`define UART_MC_OUT1 2
`define UART_MC_OUT2 3
`define UART_MC_LB 4 // Loopback mode
 
// Line Status Register bits
`define UART_LS_DR 0 // Data ready
`define UART_LS_OE 1 // Overrun Error
`define UART_LS_PE 2 // Parity Error
`define UART_LS_FE 3 // Framing Error
`define UART_LS_BI 4 // Break interrupt
`define UART_LS_TFE 5 // Transmit FIFO is empty
`define UART_LS_TE 6 // Transmitter Empty indicator
`define UART_LS_EI 7 // Error indicator
 
// Modem Status Register bits
`define UART_MS_DCTS 0 // Delta signals
`define UART_MS_DDSR 1
`define UART_MS_TERI 2
`define UART_MS_DDCD 3
`define UART_MS_CCTS 4 // Complement signals
`define UART_MS_CDSR 5
`define UART_MS_CRI 6
`define UART_MS_CDCD 7
 
// FIFO parameter defines
 
`define UART_FIFO_WIDTH 8
`define UART_FIFO_DEPTH 16
`define UART_FIFO_POINTER_W 4
`define UART_FIFO_COUNTER_W 5
// receiver fifo has width 11 because it has break, parity and framing error bits
`define UART_FIFO_REC_WIDTH 11
 
 
`define VERBOSE_WB 0 // All activity on the WISHBONE is recorded
`define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register)
`define FAST_TEST 1 // 64/1024 packets are sent
 
 
 
 
 
 
 
/tags/rel_3/rtl/verilog/uart_rfifo.v
0,0 → 1,320
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_rfifo.v (Modified from uart_fifo.v) ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core receiver FIFO ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2002/07/22 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.3 2003/06/11 16:37:47 gorban
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
//
// Revision 1.2 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.1 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.16 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.15 2001/12/18 09:01:07 mohor
// Bug that was entered in the last update fixed (rx state machine).
//
// Revision 1.14 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.13 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.12 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.11 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/24 08:48:10 mohor
// FIFO was not cleared after the data was read bug fixed.
//
// Revision 1.7 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.3 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:48 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
module uart_rfifo (clk,
wb_rst_i, data_in, data_out,
// Control signals
push, // push strobe, active high
pop, // pop strobe, active high
// status signals
overrun,
count,
error_bit,
fifo_reset,
reset_status
);
 
 
// FIFO parameters
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
 
input clk;
input wb_rst_i;
input push;
input pop;
input [fifo_width-1:0] data_in;
input fifo_reset;
input reset_status;
 
output [fifo_width-1:0] data_out;
output overrun;
output [fifo_counter_w-1:0] count;
output error_bit;
 
wire [fifo_width-1:0] data_out;
wire [7:0] data8_out;
// flags FIFO
reg [2:0] fifo[fifo_depth-1:0];
 
// FIFO pointers
reg [fifo_pointer_w-1:0] top;
reg [fifo_pointer_w-1:0] bottom;
 
reg [fifo_counter_w-1:0] count;
reg overrun;
 
wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
 
raminfr #(fifo_pointer_w,8,fifo_depth) rfifo
(.clk(clk),
.we(push),
.a(top),
.dpra(bottom),
.di(data_in[fifo_width-1:fifo_width-8]),
.dpo(data8_out)
);
 
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
begin
top <= #1 0;
bottom <= #1 1'b0;
count <= #1 0;
fifo[0] <= #1 0;
fifo[1] <= #1 0;
fifo[2] <= #1 0;
fifo[3] <= #1 0;
fifo[4] <= #1 0;
fifo[5] <= #1 0;
fifo[6] <= #1 0;
fifo[7] <= #1 0;
fifo[8] <= #1 0;
fifo[9] <= #1 0;
fifo[10] <= #1 0;
fifo[11] <= #1 0;
fifo[12] <= #1 0;
fifo[13] <= #1 0;
fifo[14] <= #1 0;
fifo[15] <= #1 0;
end
else
if (fifo_reset) begin
top <= #1 0;
bottom <= #1 1'b0;
count <= #1 0;
fifo[0] <= #1 0;
fifo[1] <= #1 0;
fifo[2] <= #1 0;
fifo[3] <= #1 0;
fifo[4] <= #1 0;
fifo[5] <= #1 0;
fifo[6] <= #1 0;
fifo[7] <= #1 0;
fifo[8] <= #1 0;
fifo[9] <= #1 0;
fifo[10] <= #1 0;
fifo[11] <= #1 0;
fifo[12] <= #1 0;
fifo[13] <= #1 0;
fifo[14] <= #1 0;
fifo[15] <= #1 0;
end
else
begin
case ({push, pop})
2'b10 : if (count<fifo_depth) // overrun condition
begin
top <= #1 top_plus_1;
fifo[top] <= #1 data_in[2:0];
count <= #1 count + 1'b1;
end
2'b01 : if(count>0)
begin
fifo[bottom] <= #1 0;
bottom <= #1 bottom + 1'b1;
count <= #1 count - 1'b1;
end
2'b11 : begin
bottom <= #1 bottom + 1'b1;
top <= #1 top_plus_1;
fifo[top] <= #1 data_in[2:0];
end
default: ;
endcase
end
end // always
 
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
overrun <= #1 1'b0;
else
if(fifo_reset | reset_status)
overrun <= #1 1'b0;
else
if(push & ~pop & (count==fifo_depth))
overrun <= #1 1'b1;
end // always
 
 
// please note though that data_out is only valid one clock after pop signal
assign data_out = {data8_out,fifo[bottom]};
 
// Additional logic for detection of error conditions (parity and framing) inside the FIFO
// for the Line Status Register bit 7
 
wire [2:0] word0 = fifo[0];
wire [2:0] word1 = fifo[1];
wire [2:0] word2 = fifo[2];
wire [2:0] word3 = fifo[3];
wire [2:0] word4 = fifo[4];
wire [2:0] word5 = fifo[5];
wire [2:0] word6 = fifo[6];
wire [2:0] word7 = fifo[7];
 
wire [2:0] word8 = fifo[8];
wire [2:0] word9 = fifo[9];
wire [2:0] word10 = fifo[10];
wire [2:0] word11 = fifo[11];
wire [2:0] word12 = fifo[12];
wire [2:0] word13 = fifo[13];
wire [2:0] word14 = fifo[14];
wire [2:0] word15 = fifo[15];
 
// a 1 is returned if any of the error bits in the fifo is 1
assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] |
word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] |
word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] |
word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
 
endmodule
/tags/rel_3/rtl/verilog/uart_top.v
0,0 → 1,340
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_top.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core top level. ////
//// ////
//// Known problems (limits): ////
//// Note that transmitter and receiver instances are inside ////
//// the uart_regs.v file. ////
//// ////
//// To Do: ////
//// Nothing so far. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.18 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.17 2001/12/19 08:40:03 mohor
// Warnings fixed (unused signals removed).
//
// Revision 1.16 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.15 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.14 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.13 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.12 2001/08/25 15:46:19 gorban
// Modified port names again
//
// Revision 1.11 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.10 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
module uart_top (
wb_clk_i,
// Wishbone signals
wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_sel_i,
int_o, // interrupt request
 
// UART signals
// serial input/output
stx_pad_o, srx_pad_i,
 
// modem signals
rts_pad_o, cts_pad_i, dtr_pad_o, dsr_pad_i, ri_pad_i, dcd_pad_i
`ifdef UART_HAS_BAUDRATE_OUTPUT
, baud_o
`endif
);
 
parameter uart_data_width = `UART_DATA_WIDTH;
parameter uart_addr_width = `UART_ADDR_WIDTH;
 
input wb_clk_i;
 
// WISHBONE interface
input wb_rst_i;
input [uart_addr_width-1:0] wb_adr_i;
input [uart_data_width-1:0] wb_dat_i;
output [uart_data_width-1:0] wb_dat_o;
input wb_we_i;
input wb_stb_i;
input wb_cyc_i;
input [3:0] wb_sel_i;
output wb_ack_o;
output int_o;
 
// UART signals
input srx_pad_i;
output stx_pad_o;
output rts_pad_o;
input cts_pad_i;
output dtr_pad_o;
input dsr_pad_i;
input ri_pad_i;
input dcd_pad_i;
 
// optional baudrate output
`ifdef UART_HAS_BAUDRATE_OUTPUT
output baud_o;
`endif
 
 
wire stx_pad_o;
wire rts_pad_o;
wire dtr_pad_o;
 
wire [uart_addr_width-1:0] wb_adr_i;
wire [uart_data_width-1:0] wb_dat_i;
wire [uart_data_width-1:0] wb_dat_o;
 
wire [7:0] wb_dat8_i; // 8-bit internal data input
wire [7:0] wb_dat8_o; // 8-bit internal data output
wire [31:0] wb_dat32_o; // debug interface 32-bit output
wire [3:0] wb_sel_i; // WISHBONE select signal
wire [uart_addr_width-1:0] wb_adr_int;
wire we_o; // Write enable for registers
wire re_o; // Read enable for registers
//
// MODULE INSTANCES
//
 
`ifdef DATA_BUS_WIDTH_8
`else
// debug interface wires
wire [3:0] ier;
wire [3:0] iir;
wire [1:0] fcr;
wire [4:0] mcr;
wire [7:0] lcr;
wire [7:0] msr;
wire [7:0] lsr;
wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
wire [2:0] tstate;
wire [3:0] rstate;
`endif
 
`ifdef DATA_BUS_WIDTH_8
//// WISHBONE interface module
uart_wb wb_interface(
.clk( wb_clk_i ),
.wb_rst_i( wb_rst_i ),
.wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o),
.wb_dat8_i(wb_dat8_i),
.wb_dat8_o(wb_dat8_o),
.wb_dat32_o(32'b0),
.wb_sel_i(4'b0),
.wb_we_i( wb_we_i ),
.wb_stb_i( wb_stb_i ),
.wb_cyc_i( wb_cyc_i ),
.wb_ack_o( wb_ack_o ),
.wb_adr_i(wb_adr_i),
.wb_adr_int(wb_adr_int),
.we_o( we_o ),
.re_o(re_o)
);
`else
uart_wb wb_interface(
.clk( wb_clk_i ),
.wb_rst_i( wb_rst_i ),
.wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o),
.wb_dat8_i(wb_dat8_i),
.wb_dat8_o(wb_dat8_o),
.wb_sel_i(wb_sel_i),
.wb_dat32_o(wb_dat32_o),
.wb_we_i( wb_we_i ),
.wb_stb_i( wb_stb_i ),
.wb_cyc_i( wb_cyc_i ),
.wb_ack_o( wb_ack_o ),
.wb_adr_i(wb_adr_i),
.wb_adr_int(wb_adr_int),
.we_o( we_o ),
.re_o(re_o)
);
`endif
 
// Registers
uart_regs regs(
.clk( wb_clk_i ),
.wb_rst_i( wb_rst_i ),
.wb_addr_i( wb_adr_int ),
.wb_dat_i( wb_dat8_i ),
.wb_dat_o( wb_dat8_o ),
.wb_we_i( we_o ),
.wb_re_i(re_o),
.modem_inputs( {cts_pad_i, dsr_pad_i,
ri_pad_i, dcd_pad_i} ),
.stx_pad_o( stx_pad_o ),
.srx_pad_i( srx_pad_i ),
`ifdef DATA_BUS_WIDTH_8
`else
// debug interface signals enabled
.ier(ier),
.iir(iir),
.fcr(fcr),
.mcr(mcr),
.lcr(lcr),
.msr(msr),
.lsr(lsr),
.rf_count(rf_count),
.tf_count(tf_count),
.tstate(tstate),
.rstate(rstate),
`endif
.rts_pad_o( rts_pad_o ),
.dtr_pad_o( dtr_pad_o ),
.int_o( int_o )
`ifdef UART_HAS_BAUDRATE_OUTPUT
, .baud_o(baud_o)
`endif
 
);
 
`ifdef DATA_BUS_WIDTH_8
`else
uart_debug_if dbg(/*AUTOINST*/
// Outputs
.wb_dat32_o (wb_dat32_o[31:0]),
// Inputs
.wb_adr_i (wb_adr_int[`UART_ADDR_WIDTH-1:0]),
.ier (ier[3:0]),
.iir (iir[3:0]),
.fcr (fcr[1:0]),
.mcr (mcr[4:0]),
.lcr (lcr[7:0]),
.msr (msr[7:0]),
.lsr (lsr[7:0]),
.rf_count (rf_count[`UART_FIFO_COUNTER_W-1:0]),
.tf_count (tf_count[`UART_FIFO_COUNTER_W-1:0]),
.tstate (tstate[2:0]),
.rstate (rstate[3:0]));
`endif
 
initial
begin
`ifdef DATA_BUS_WIDTH_8
$display("(%m) UART INFO: Data bus width is 8. No Debug interface.\n");
`else
$display("(%m) UART INFO: Data bus width is 32. Debug Interface present.\n");
`endif
`ifdef UART_HAS_BAUDRATE_OUTPUT
$display("(%m) UART INFO: Has baudrate output\n");
`else
$display("(%m) UART INFO: Doesn't have baudrate output\n");
`endif
end
 
endmodule
 
 
/tags/rel_3/rtl/verilog/raminfr.v
0,0 → 1,111
//////////////////////////////////////////////////////////////////////
//// ////
//// raminfr.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Inferrable Distributed RAM for FIFOs ////
//// ////
//// Known problems (limits): ////
//// None . ////
//// ////
//// To Do: ////
//// Nothing so far. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// ////
//// Created: 2002/07/22 ////
//// Last Updated: 2002/07/22 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.1 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
 
//Following is the Verilog code for a dual-port RAM with asynchronous read.
module raminfr
(clk, we, a, dpra, di, dpo);
 
parameter addr_width = 4;
parameter data_width = 8;
parameter depth = 16;
 
input clk;
input we;
input [addr_width-1:0] a;
input [addr_width-1:0] dpra;
input [data_width-1:0] di;
//output [data_width-1:0] spo;
output [data_width-1:0] dpo;
reg [data_width-1:0] ram [depth-1:0];
 
wire [data_width-1:0] dpo;
wire [data_width-1:0] di;
wire [addr_width-1:0] a;
wire [addr_width-1:0] dpra;
always @(posedge clk) begin
if (we)
ram[a] <= di;
end
// assign spo = ram[a];
assign dpo = ram[dpra];
endmodule
 
/tags/rel_3/rtl/verilog/uart_debug_if.v
0,0 → 1,126
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_debug_if.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core debug interface. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// ////
//// Created: 2001/12/02 ////
//// (See log for the revision history) ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.4 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.3 2001/12/19 08:40:03 mohor
// Warnings fixed (unused signals removed).
//
// Revision 1.2 2001/12/12 22:17:30 gorban
// some synthesis bugs fixed
//
// Revision 1.1 2001/12/04 21:14:16 gorban
// committed the debug interface file
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
module uart_debug_if (/*AUTOARG*/
// Outputs
wb_dat32_o,
// Inputs
wb_adr_i, ier, iir, fcr, mcr, lcr, msr,
lsr, rf_count, tf_count, tstate, rstate
) ;
 
input [`UART_ADDR_WIDTH-1:0] wb_adr_i;
output [31:0] wb_dat32_o;
input [3:0] ier;
input [3:0] iir;
input [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
input [4:0] mcr;
input [7:0] lcr;
input [7:0] msr;
input [7:0] lsr;
input [`UART_FIFO_COUNTER_W-1:0] rf_count;
input [`UART_FIFO_COUNTER_W-1:0] tf_count;
input [2:0] tstate;
input [3:0] rstate;
 
 
wire [`UART_ADDR_WIDTH-1:0] wb_adr_i;
reg [31:0] wb_dat32_o;
 
always @(/*AUTOSENSE*/fcr or ier or iir or lcr or lsr or mcr or msr
or rf_count or rstate or tf_count or tstate or wb_adr_i)
case (wb_adr_i)
// 8 + 8 + 4 + 4 + 8
5'b01000: wb_dat32_o = {msr,lcr,iir,ier,lsr};
// 5 + 2 + 5 + 4 + 5 + 3
5'b01100: wb_dat32_o = {8'b0, fcr,mcr, rf_count, rstate, tf_count, tstate};
default: wb_dat32_o = 0;
endcase // case(wb_adr_i)
 
endmodule // uart_debug_if
 
/tags/rel_3/rtl/verilog/uart_tfifo.v
0,0 → 1,243
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_tfifo.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core transmitter FIFO ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2002/07/22 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.1 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.16 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.15 2001/12/18 09:01:07 mohor
// Bug that was entered in the last update fixed (rx state machine).
//
// Revision 1.14 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.13 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.12 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.11 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/24 08:48:10 mohor
// FIFO was not cleared after the data was read bug fixed.
//
// Revision 1.7 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.3 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:48 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
module uart_tfifo (clk,
wb_rst_i, data_in, data_out,
// Control signals
push, // push strobe, active high
pop, // pop strobe, active high
// status signals
overrun,
count,
fifo_reset,
reset_status
);
 
 
// FIFO parameters
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
 
input clk;
input wb_rst_i;
input push;
input pop;
input [fifo_width-1:0] data_in;
input fifo_reset;
input reset_status;
 
output [fifo_width-1:0] data_out;
output overrun;
output [fifo_counter_w-1:0] count;
 
wire [fifo_width-1:0] data_out;
 
// FIFO pointers
reg [fifo_pointer_w-1:0] top;
reg [fifo_pointer_w-1:0] bottom;
 
reg [fifo_counter_w-1:0] count;
reg overrun;
wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
 
raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo
(.clk(clk),
.we(push),
.a(top),
.dpra(bottom),
.di(data_in),
.dpo(data_out)
);
 
 
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
begin
top <= #1 0;
bottom <= #1 1'b0;
count <= #1 0;
end
else
if (fifo_reset) begin
top <= #1 0;
bottom <= #1 1'b0;
count <= #1 0;
end
else
begin
case ({push, pop})
2'b10 : if (count<fifo_depth) // overrun condition
begin
top <= #1 top_plus_1;
count <= #1 count + 1'b1;
end
2'b01 : if(count>0)
begin
bottom <= #1 bottom + 1'b1;
count <= #1 count - 1'b1;
end
2'b11 : begin
bottom <= #1 bottom + 1'b1;
top <= #1 top_plus_1;
end
default: ;
endcase
end
end // always
 
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
overrun <= #1 1'b0;
else
if(fifo_reset | reset_status)
overrun <= #1 1'b0;
else
if(push & (count==fifo_depth))
overrun <= #1 1'b1;
end // always
 
endmodule
/tags/rel_3/rtl/verilog/uart_transmitter.v
0,0 → 1,351
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_transmitter.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core transmitter logic ////
//// ////
//// Known problems (limits): ////
//// None known ////
//// ////
//// To Do: ////
//// Thourough testing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 $
// Revision 1.18 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.16 2002/01/08 11:29:40 mohor
// tf_pop was too wide. Now it is only 1 clk cycle width.
//
// Revision 1.15 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.14 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.13 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.12 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.11 2001/10/29 17:00:46 gorban
// fixed parity sending and tx_fifo resets over- and underrun
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.6 2001/06/23 11:21:48 gorban
// DL made 16-bit long. Fixed transmission/reception bugs.
//
// Revision 1.5 2001/06/02 14:28:14 gorban
// Fixed receiver and transmitter. Major bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:49 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.1 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "uart_defines.v"
 
module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, tstate, tf_count, tx_reset, lsr_mask);
 
input clk;
input wb_rst_i;
input [7:0] lcr;
input tf_push;
input [7:0] wb_dat_i;
input enable;
input tx_reset;
input lsr_mask; //reset of fifo
output stx_pad_o;
output [2:0] tstate;
output [`UART_FIFO_COUNTER_W-1:0] tf_count;
 
reg [2:0] tstate;
reg [4:0] counter;
reg [2:0] bit_counter; // counts the bits to be sent
reg [6:0] shift_out; // output shift register
reg stx_o_tmp;
reg parity_xor; // parity of the word
reg tf_pop;
reg bit_out;
 
// TX FIFO instance
//
// Transmitter FIFO signals
wire [`UART_FIFO_WIDTH-1:0] tf_data_in;
wire [`UART_FIFO_WIDTH-1:0] tf_data_out;
wire tf_push;
wire tf_overrun;
wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
 
assign tf_data_in = wb_dat_i;
 
uart_tfifo fifo_tx( // error bit signal is not used in transmitter FIFO
.clk( clk ),
.wb_rst_i( wb_rst_i ),
.data_in( tf_data_in ),
.data_out( tf_data_out ),
.push( tf_push ),
.pop( tf_pop ),
.overrun( tf_overrun ),
.count( tf_count ),
.fifo_reset( tx_reset ),
.reset_status(lsr_mask)
);
 
// TRANSMITTER FINAL STATE MACHINE
 
parameter s_idle = 3'd0;
parameter s_send_start = 3'd1;
parameter s_send_byte = 3'd2;
parameter s_send_parity = 3'd3;
parameter s_send_stop = 3'd4;
parameter s_pop_byte = 3'd5;
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
tstate <= #1 s_idle;
stx_o_tmp <= #1 1'b1;
counter <= #1 5'b0;
shift_out <= #1 7'b0;
bit_out <= #1 1'b0;
parity_xor <= #1 1'b0;
tf_pop <= #1 1'b0;
bit_counter <= #1 3'b0;
end
else
if (enable)
begin
case (tstate)
s_idle : if (~|tf_count) // if tf_count==0
begin
tstate <= #1 s_idle;
stx_o_tmp <= #1 1'b1;
end
else
begin
tf_pop <= #1 1'b0;
stx_o_tmp <= #1 1'b1;
tstate <= #1 s_pop_byte;
end
s_pop_byte : begin
tf_pop <= #1 1'b1;
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
2'b00 : begin
bit_counter <= #1 3'b100;
parity_xor <= #1 ^tf_data_out[4:0];
end
2'b01 : begin
bit_counter <= #1 3'b101;
parity_xor <= #1 ^tf_data_out[5:0];
end
2'b10 : begin
bit_counter <= #1 3'b110;
parity_xor <= #1 ^tf_data_out[6:0];
end
2'b11 : begin
bit_counter <= #1 3'b111;
parity_xor <= #1 ^tf_data_out[7:0];
end
endcase
{shift_out[6:0], bit_out} <= #1 tf_data_out;
tstate <= #1 s_send_start;
end
s_send_start : begin
tf_pop <= #1 1'b0;
if (~|counter)
counter <= #1 5'b01111;
else
if (counter == 5'b00001)
begin
counter <= #1 0;
tstate <= #1 s_send_byte;
end
else
counter <= #1 counter - 1'b1;
stx_o_tmp <= #1 1'b0;
end
s_send_byte : begin
if (~|counter)
counter <= #1 5'b01111;
else
if (counter == 5'b00001)
begin
if (bit_counter > 3'b0)
begin
bit_counter <= #1 bit_counter - 1'b1;
{shift_out[5:0],bit_out } <= #1 {shift_out[6:1], shift_out[0]};
tstate <= #1 s_send_byte;
end
else // end of byte
if (~lcr[`UART_LC_PE])
begin
tstate <= #1 s_send_stop;
end
else
begin
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
2'b00: bit_out <= #1 ~parity_xor;
2'b01: bit_out <= #1 1'b1;
2'b10: bit_out <= #1 parity_xor;
2'b11: bit_out <= #1 1'b0;
endcase
tstate <= #1 s_send_parity;
end
counter <= #1 0;
end
else
counter <= #1 counter - 1'b1;
stx_o_tmp <= #1 bit_out; // set output pin
end
s_send_parity : begin
if (~|counter)
counter <= #1 5'b01111;
else
if (counter == 5'b00001)
begin
counter <= #1 4'b0;
tstate <= #1 s_send_stop;
end
else
counter <= #1 counter - 1'b1;
stx_o_tmp <= #1 bit_out;
end
s_send_stop : begin
if (~|counter)
begin
casex ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]})
3'b0xx: counter <= #1 5'b01101; // 1 stop bit ok igor
3'b100: counter <= #1 5'b10101; // 1.5 stop bit
default: counter <= #1 5'b11101; // 2 stop bits
endcase
end
else
if (counter == 5'b00001)
begin
counter <= #1 0;
tstate <= #1 s_idle;
end
else
counter <= #1 counter - 1'b1;
stx_o_tmp <= #1 1'b1;
end
 
default : // should never get here
tstate <= #1 s_idle;
endcase
end // end if enable
else
tf_pop <= #1 1'b0; // tf_pop must be 1 cycle width
end // transmitter logic
 
assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp; // Break condition
endmodule
/tags/rel_3/rtl/verilog/timescale.v
0,0 → 1,64
//////////////////////////////////////////////////////////////////////
//// ////
//// timescale.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Defines of the Core ////
//// ////
//// Known problems (limits): ////
//// None ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
// Timescale define
 
`timescale 1ns/10ps
/tags/rel_3/rtl/verilog-backup/uart_regs.v Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/rel_3/rtl/verilog-backup/uart_regs.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/uart_top.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/uart_top.v =================================================================== --- tags/rel_3/rtl/verilog-backup/uart_top.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/uart_top.v (revision 102)
tags/rel_3/rtl/verilog-backup/uart_top.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/uart_fifo.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/uart_fifo.v =================================================================== --- tags/rel_3/rtl/verilog-backup/uart_fifo.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/uart_fifo.v (revision 102)
tags/rel_3/rtl/verilog-backup/uart_fifo.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/uart_receiver.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/uart_receiver.v =================================================================== --- tags/rel_3/rtl/verilog-backup/uart_receiver.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/uart_receiver.v (revision 102)
tags/rel_3/rtl/verilog-backup/uart_receiver.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/uart_wb.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/uart_wb.v =================================================================== --- tags/rel_3/rtl/verilog-backup/uart_wb.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/uart_wb.v (revision 102)
tags/rel_3/rtl/verilog-backup/uart_wb.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/timescale.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/timescale.v =================================================================== --- tags/rel_3/rtl/verilog-backup/timescale.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/timescale.v (revision 102)
tags/rel_3/rtl/verilog-backup/timescale.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/uart_transmitter.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/uart_transmitter.v =================================================================== --- tags/rel_3/rtl/verilog-backup/uart_transmitter.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/uart_transmitter.v (revision 102)
tags/rel_3/rtl/verilog-backup/uart_transmitter.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/verilog-backup/uart_defines.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/rtl/verilog-backup/uart_defines.v =================================================================== --- tags/rel_3/rtl/verilog-backup/uart_defines.v (nonexistent) +++ tags/rel_3/rtl/verilog-backup/uart_defines.v (revision 102)
tags/rel_3/rtl/verilog-backup/uart_defines.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/rtl/vhdl/.keepme =================================================================== Index: tags/rel_3/sim/rtl_sim/log/uart_interrupts_verbose.log =================================================================== --- tags/rel_3/sim/rtl_sim/log/uart_interrupts_verbose.log (nonexistent) +++ tags/rel_3/sim/rtl_sim/log/uart_interrupts_verbose.log (revision 102) @@ -0,0 +1,104 @@ + +--------------------------------------------------------------------------- +- Initialization of UART. +--------------------------------------------------------------------------- + +Time: 200 (testbench_utilities.do_reset) +*N, RESET signal asynchronously set. +Time: 200 (testbench_utilities.disable_clk_generators) +*N, Following clocks are DISABLED: +Time: 200 (testbench_utilities.disable_clk_generators) +*N, - WB_clk +Time: 200 (testbench_utilities.disable_clk_generators) +*N, - RX_clk +Time: 200 (testbench_utilities.disable_clk_generators) +*N, - TX_clk +Time: 200 (testbench_utilities.disable_clk_generators) +*N, - TX_clk_divided +Time: 200 (testbench_utilities.set_device_tx_rx_clk_divisor) +*N, UART DEVICE TX/RX clock divisor: 1000. +Time: 200 (testbench_utilities.set_wb_clock_period) +*N, WB & UART DEVICE TX/RX clock period: 64. +Time: 200 (testbench_utilities.enable_clk_generators) +*N, Following clocks are ENABLED: +Time: 200 (testbench_utilities.enable_clk_generators) +*N, - WB_clk +Time: 200 (testbench_utilities.enable_clk_generators) +*N, - RX_clk +Time: 200 (testbench_utilities.enable_clk_generators) +*N, - TX_clk +Time: 200 (testbench_utilities.enable_clk_generators) +*N, - TX_clk_divided +Time: 11100 (testbench_utilities.release_reset) +*N, RESET signal released synchronously to WB clk. +Time: 11100 (uart_wb_utilities.write_dlr) +*N, DLAB in LC Register is going to be 1. +Time: 11100 (uart_wb_utilities.write_dlr) +*N, Current LCR = 3. +Time: 11100 (uart_wb_utilities.write_lcr) +*N, WRITING UART's LC Register. +Time: 101000 (uart_wb_utilities.write_lcr) +*N, Write LCR = 83. +Time: 101000 (uart_wb_utilities.write_dlr) +*N, WRITING UART's DL Register [15:8]. +Time: 161000 (uart_wb_utilities.write_dlr) +*N, Write DLR [15:8] = 10. +Time: 161000 (uart_wb_utilities.write_dlr) +*N, WRITING UART's DL Register [ 7:0]. +Time: 281000 (uart_wb_utilities.write_dlr) +*N, Write DLR [ 7:0] = 0. +Time: 281000 (uart_wb_utilities.write_dlr) +*N, DLAB in LC Register is going to be 0. +Time: 281000 (uart_wb_utilities.write_lcr) +*N, WRITING UART's LC Register. +Time: 371000 (uart_wb_utilities.write_lcr) +*N, Write LCR = 3. +Time: 371000 (uart_wb_utilities.write_ier) +*N, WRITING UART's IE Register. +Time: 411000 (uart_wb_utilities.write_ier) +*N, Write IER = 7. +Time: 411000 (uart_wb_utilities.write_fcr) +*N, WRITING UART's FC Register. +Time: 511000 (uart_wb_utilities.write_fcr) +*N, Write FCR = c0. +Time: 511000 (uart_wb_utilities.write_lcr) +*N, WRITING UART's LC Register. +Time: 621000 (uart_wb_utilities.write_lcr) +*N, Write LCR = 3. +Time: 621000 (uart_device_utilities.set_rx_length) +*N, SETTING RX CHAR length. +Time: 621000 (uart_device_utilities.set_rx_length) +*N, Length: 8. +Time: 621000 (uart_device_utilities.disable_rx_parity) +*N, DISABLING RX CHAR parity. +Time: 621000 (uart_device_utilities.set_rx_second_stop_bit) +*N, SETTING RX CHAR 1 stop bit. +Time: 621000 (uart_device_utilities.set_tx_length) +*N, SETTING TX CHAR length. +Time: 621000 (uart_device_utilities.set_tx_length) +*N, Length: 8. +Time: 621000 (uart_device_utilities.disable_tx_parity) +*N, DISABLING TX CHAR parity. +Time: 621000 (uart_device_utilities.correct_tx_parity) +*N, DISABLING WRONG parity generation. +Time: 621000 (uart_device_utilities.correct_tx_frame) +*N, DISABLING WRONG frame generation. +Time: 621000 (uart_device_utilities.generate_tx_glitch) +*N, DISABLING 1 TIME glitch generation with CLKs delay. +Time: 621000 (uart_device_utilities.generate_tx_glitch) +*N, CLKs delay from start bit edge: 0. + +--------------------------------------------------------------------------- +- Interrupt test. +--------------------------------------------------------------------------- + +Time: 621000 (testbench_utilities.wait_for_num_of_wb_clk) +*N, Waiting for following number of WB CLK periods: +Time: 621000 (testbench_utilities.wait_for_num_of_wb_clk) +*N, Waiting for following number of WB CLK periods: 450000. +Time: 701000 (uart_wb_utilities.write_char) +*N, Write TRR = aa. +Time: 5734501000 (testbench.write_tx_shift_reg_read_tx_fifo) +*N, TX FIFO is empty! +Time: 5734521200 (testbench.tx_fifo_status_changing) +*E, Bit 5 of LSR register not '1'! Index: tags/rel_3/sim/rtl_sim/log/uart_interrupts_report.log =================================================================== --- tags/rel_3/sim/rtl_sim/log/uart_interrupts_report.log (nonexistent) +++ tags/rel_3/sim/rtl_sim/log/uart_interrupts_report.log (revision 102) @@ -0,0 +1,23 @@ + +--------------------------------------------------------------------------- + +Initialization of UART. + PASSED! + Simulation Time: 621000 + +--------------------------------------------------------------------------- + +Interrupt test. + FAILED! + Failure message: Bit 5 of LSR register not '1'!. + Simulation Time: 5734521200 + +--------------------------------------------------------------------------- + +TEST CASE execution summary: +Number of tests PASSED=1 +Number of tests FAILED=1 + Simulation End Time: 5834521200 + +--------------------------------------------------------------------------- + Index: tags/rel_3/sim/rtl_sim/log/.keepme =================================================================== Index: tags/rel_3/sim/rtl_sim/run/run_sim.scr =================================================================== --- tags/rel_3/sim/rtl_sim/run/run_sim.scr (nonexistent) +++ tags/rel_3/sim/rtl_sim/run/run_sim.scr (revision 102) @@ -0,0 +1,345 @@ +#!/bin/csh -f + + +# GLOBAL VARIABLES +################### + +set sim_top = testbench; +set arg_tool = "NCSim"; # By default NCSim is used as simulation tool +set arg_wave = 0; # By default waveform is not recorded +set arg_verb = 0; # By default basic display on monitor (no verbose) +set arg_test = 0; # By default all testcases are simulated + + +# GETTING PARAMETERS FROM COMMAND LINE +####################################### + +set cur_arg = 1; + +if ($#argv < 1) then + echo "" + echo " Verification without any argument:" +else + + while ($cur_arg <= $#argv) + + switch ("$argv[$cur_arg]") + # HELP ARGUMENT + case "-h": + goto help + breaksw + case "help": + goto help + breaksw + # TOOL ARGUMENT + case "-m": + set arg_tool = "ModelSim"; + echo " $argv[$cur_arg] - ModelSim tool" + breaksw + case "modelsim" + set arg_tool = "ModelSim"; + echo " $argv[$cur_arg] - ModelSim tool" + breaksw + # WAVEFORM ARGUMENT + case "-w": + @ arg_wave = 1; + echo " $argv[$cur_arg] - Waveform" + breaksw + case "waveform": + @ arg_wave = 1; + echo " $argv[$cur_arg] - Waveform" + breaksw + # VERBOSE ARGUMENT + case "-v": + @ arg_verb = 1; + echo " $argv[$cur_arg] - Verbose" + breaksw + case "verbose": + @ arg_verb = 1; + echo " $argv[$cur_arg] - Verbose" + breaksw + # TESTCASE ARGUMENT + default: + if (-e ../../../bench/verilog/testcases/$argv[$cur_arg].v) then + set arg_test = $argv[$cur_arg]; + echo " $argv[$cur_arg] - Testcase" + # INVALID ARGUMENT + else + echo "" + echo " Invalid verification argument: $argv[$cur_arg]" + goto help + endif + breaksw + endsw + + @ cur_arg++ + end + +endif + + +# SIMULATION LOOP +################## + +set cur_test_num = 0; + +simulate: + + + # DELETING FILES + ################# + + # Prepared files + if (-e ./file_list.lst) then + rm -rf ./file_list.lst + endif + if (-e ../bin/cds.lib) then + rm -rf ../bin/cds.lib + endif + if (-e ../bin/hdl.var) then + rm -rf ../bin/hdl.var + endif + if (-e ./compile.args) then + rm -rf ./compile.args + endif + if (-e ./elab.args) then + rm -rf ./elab.args + endif + if (-e ./sim.args) then + rm -rf ./sim.args + endif + if (-e ./sim.tcl) then + rm -rf ./sim.tcl + endif + if (-e ./sim.do) then + rm -rf ./sim.do + endif + + # Projects, Libraries and Logs + if (-e ./uart.mpf) then + rm -rf ./uart.mpf + endif + if (-e ./work) then + rm -rf ./work + endif + if (-e ./INCA_libs/worklib) then + rm -rf ./INCA_libs/worklib + endif + + + # PREPARING FILE LIST + ###################### + + # Design files + echo "../../../rtl/verilog/uart_top.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_wb.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_transmitter.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_receiver.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_tfifo.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_rfifo.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_regs.v" >> ./file_list.lst + echo "../../../rtl/verilog/uart_debug_if.v" >> ./file_list.lst + + # Testcase file + if ($arg_test == 0) then + set i = 0; + foreach testcase (../../../bench/verilog/testcases/uart*.v) + if ($i == $cur_test_num) then + set testcase_i = $testcase:t:r + endif + @ i++ + end + set max_test_num = $i; + else + set testcase_i = $arg_test; + set max_test_num = 1; + endif + echo "//////////////////////////////////////////////////" > ./file_list.lst + echo "// File created within script ${0}" >> ./file_list.lst + echo "// path: $cwd" >> ./file_list.lst + echo "// user: $user" >> ./file_list.lst + echo "//////////////////////////////////////////////////" >> ./file_list.lst + echo "../../../bench/verilog/testcases/$testcase_i.v" >> ./file_list.lst + # Delete vawe out file for this testcase, if it already exists + if (-e ../out/$testcase_i.wlf) then + rm -rf ../out/$testcase_i.wlf + endif + # Delete log out file for this testcase, if it already exists + if (-e ../log/$testcase_i.log) then + rm -rf ../log/$testcase_i.log + endif + + # Testbench files + echo "../../../bench/verilog/uart_testbench.v" >> ./file_list.lst + echo "../../../bench/verilog/wb_master_model.v" >> ./file_list.lst + echo "../../../bench/verilog/uart_device.v" >> ./file_list.lst + echo "../../../bench/verilog/uart_testbench_utilities.v" >> ./file_list.lst + echo "../../../bench/verilog/uart_wb_utilities.v" >> ./file_list.lst + echo "../../../bench/verilog/uart_device_utilities.v" >> ./file_list.lst + + + # COMPILING & ELABORATING + ########################## + + if ("$arg_tool" == "NCSim") then + + # cds.lib library file + echo "//////////////////////////////////////////////////" > ../bin/cds.lib + echo "// File created within script ${0}" >> ../bin/cds.lib + echo "// path: $cwd" >> ../bin/cds.lib + echo "// user: $0" >> ../bin/cds.lib + echo "//////////////////////////////////////////////////" >> ../bin/cds.lib + echo "DEFINE worklib ./INCA_libs/worklib" >> ../bin/cds.lib + + # hdl.var variable file + echo "//////////////////////////////////////////////////" > ../bin/hdl.var + echo "// File created within script ${0}" >> ../bin/hdl.var + echo "// path: $cwd" >> ../bin/hdl.var + echo "// user: $0" >> ../bin/hdl.var + echo "//////////////////////////////////////////////////" >> ../bin/hdl.var + echo "INCLUDE \$CDS_INST_DIR/tools/inca/files/hdl.var" >> ../bin/hdl.var + echo "DEFINE WORK worklib" >> ../bin/hdl.var + + # compile.args argument file + echo "//////////////////////////////////////////////////" > ./compile.args + echo "// File created within script ${0}" >> ./compile.args + echo "// path: $cwd" >> ./compile.args + echo "// user: $0" >> ./compile.args + echo "//////////////////////////////////////////////////" >> ./compile.args + echo "-CDSLIB ../bin/cds.lib" >> ./compile.args + echo "-HDLVAR ../bin/hdl.var" >> ./compile.args + echo "-MESSAGES" >> ./compile.args + echo "-NOCOPYRIGHT" >> ./compile.args + echo "-INCDIR ../../../rtl/verilog" >> ./compile.args + echo "-INCDIR ../../../bench/verilog" >> ./compile.args + echo "-INCDIR ../../../bench/verilog/testcases" >> ./compile.args + if ($arg_verb == 1) then + echo "-DEFINE VERBOSE" >> ./compile.args + endif + cat ./file_list.lst >> ./compile.args + + # compiling + ncvlog -LOGFILE ../log/$testcase_i.compile.log -f ./compile.args #> /dev/null + + # elab.args argument file + echo "//////////////////////////////////////////////////" > ./elab.args + echo "// File created within script ${0}" >> ./elab.args + echo "// path: $cwd" >> ./elab.args + echo "// user: $0" >> ./elab.args + echo "//////////////////////////////////////////////////" >> ./elab.args + echo "-CDSLIB ../bin/cds.lib" >> ./elab.args + echo "-HDLVAR ../bin/hdl.var" >> ./elab.args + echo "-MESSAGES" >> ./elab.args + echo "-NOCOPYRIGHT" >> ./elab.args + echo "-NOTIMINGCHECKS" >> ./elab.args + echo "-SNAPSHOT worklib.testbench:rtl" >> ./elab.args + echo "-NO_TCHK_MSG" >> ./elab.args + echo "-ACCESS +RWC" >> ./elab.args + echo "worklib.$sim_top" >> ./elab.args + + # elaborating + ncelab -LOGFILE ../log/$testcase_i.elab.log -f ./elab.args #> /dev/null + else + + # compile.args argument file + echo "+libext+.v" >> ./compile.args + echo "-y ../../../rtl/verilog" >> ./compile.args + echo "-y ../../../bench/verilog" >> ./compile.args + echo "-y ../../../bench/verilog/testcases" >> ./compile.args + echo "-work ./work" >> ./compile.args + echo "+incdir+../../../rtl/verilog" >> ./compile.args + echo "+incdir+../../../bench/verilog" >> ./compile.args + echo '+define+LOG_DIR=\"../log/$testcase_i\"' >> ./compile.args + if ($arg_verb == 1) then + echo "+define+VERBOSE" >> ./compile.args + endif + cat ./file_list.lst >> ./compile.args + + # open project +# echo "project new ./ testbench ./work" >> ./sim.do + vlib -dos ./work + + # compiling + # echo "vlog -f ./compile.args" >> ./sim.do + vlog -f ./compile.args + endif + + + # SIMULATING + ############# + + if ("$arg_tool" == "NCSim") then + + # sim.args argument file + echo "//////////////////////////////////////////////////" > ./sim.args + echo "// File created within script ${0}" >> ./sim.args + echo "// path: $cwd" >> ./sim.args + echo "// user: $0" >> ./sim.args + echo "//////////////////////////////////////////////////" >> ./sim.args + echo "-CDSLIB ../bin/cds.lib" >> ./sim.args + echo "-HDLVAR ../bin/hdl.var" >> ./sim.args + echo "-MESSAGES" >> ./sim.args + echo "-NOCOPYRIGHT" >> ./sim.args + echo "-INPUT ./sim.tcl" >> ./sim.args + echo "worklib.testbench:rtl" >> ./sim.args + + # sim.tcl file + echo "//////////////////////////////////////////////////" > ./sim.tcl + echo "// File created within script ${0}" >> ./sim.tcl + echo "// path: $cwd" >> ./sim.tcl + echo "// user: $0" >> ./sim.tcl + echo "//////////////////////////////////////////////////" >> ./sim.tcl + if ($arg_wave) then + echo "database -open waves -shm -into ../out/waves.shm" >> ./sim.tcl + echo "probe -create -database waves $sim_top -shm -all -depth all" >> ./sim.tcl + echo "run" >> ./sim.tcl + else + echo "run" >> ./sim.tcl + endif + echo "quit" >> ./sim.tcl + + # simulating + ncsim -LICQUEUE -LOGFILE ../log/$testcase_i.sim.log -f ./sim.args + else + + # sim.do do file + echo "vsim work.testbench work.testbench_utilities work.uart_wb_utilities work.uart_device_utilities work.testcase -wlf ../out/$testcase_i.wlf" >> ./sim.do + if ($arg_wave) then + echo "log -r -internal -ports /testbench/*" >> ./sim.do + endif + echo "run -all" >> ./sim.do + + vsim -c -do ./sim.do + + endif + + @ cur_test_num++ + + if ($cur_test_num < $max_test_num) then + goto simulate + endif + +exit + + +# HELP DISPLAY +############### + +help: + echo "" + echo " Valid verification arguments:" + echo " 'help' / '-h' : This help is displayed" + echo " 'modelsim' / '-m' : ModelSim simulation tool is used, otherwise" + echo " NCSim is used (default)" + echo " 'waveform' / '-w' : Waveform output is recorded, otherwise" + echo " NO waveform is recorded (default)" + echo " 'verbose' / '-v' : Verbose display on monitor, otherwise" + echo " basic display on monitor (default)" + echo " '\042testcase\042' : Testcase which is going to be simulated, otherwise" + echo " ALL testcases are simulated - regression (default);" + echo " Available testcases:" + foreach testcase (../../../bench/verilog/testcases/uart*.v) + echo " "$testcase:t:r + end + echo "" +exit Index: tags/rel_3/sim/rtl_sim/run/run_signalscan =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/sim/rtl_sim/run/run_signalscan =================================================================== --- tags/rel_3/sim/rtl_sim/run/run_signalscan (nonexistent) +++ tags/rel_3/sim/rtl_sim/run/run_signalscan (revision 102)
tags/rel_3/sim/rtl_sim/run/run_signalscan Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/sim/rtl_sim/run/run_sim =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/sim/rtl_sim/run/run_sim =================================================================== --- tags/rel_3/sim/rtl_sim/run/run_sim (nonexistent) +++ tags/rel_3/sim/rtl_sim/run/run_sim (revision 102)
tags/rel_3/sim/rtl_sim/run/run_sim Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/sim/rtl_sim/bin/nc.scr =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/sim/rtl_sim/bin/nc.scr =================================================================== --- tags/rel_3/sim/rtl_sim/bin/nc.scr (nonexistent) +++ tags/rel_3/sim/rtl_sim/bin/nc.scr (revision 102)
tags/rel_3/sim/rtl_sim/bin/nc.scr Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/sim/rtl_sim/bin/sim.tcl =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/sim/rtl_sim/bin/sim.tcl =================================================================== --- tags/rel_3/sim/rtl_sim/bin/sim.tcl (nonexistent) +++ tags/rel_3/sim/rtl_sim/bin/sim.tcl (revision 102)
tags/rel_3/sim/rtl_sim/bin/sim.tcl Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/sim/rtl_sim/out/.keepme =================================================================== Index: tags/rel_3/sim/rtl_sim/src/.keepme =================================================================== Index: tags/rel_3/sim/gate_sim/log/.keepme =================================================================== Index: tags/rel_3/sim/gate_sim/run/.keepme =================================================================== Index: tags/rel_3/sim/gate_sim/out/.keepme =================================================================== Index: tags/rel_3/sim/gate_sim/src/.keepme =================================================================== Index: tags/rel_3/sim/gate_sim/bin/.keepme =================================================================== Index: tags/rel_3/bench/verilog/test_cases/uart_int.v =================================================================== --- tags/rel_3/bench/verilog/test_cases/uart_int.v (nonexistent) +++ tags/rel_3/bench/verilog/test_cases/uart_int.v (revision 102) @@ -0,0 +1,276 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// uart_int.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 "timescale.v" + +module testcase; + + +// Testcase INDEPENDENT code - common to all testcases +//##################################################### + + // Variables + // Testbench reporting events & signals + event severe_err_event; + event err_event; + event wrn_event; + event msg_event; + event val_event; + event testbench_log_written; + reg [7999: 0] tim; + reg [7999: 0] severe_err_msg; + reg [7999: 0] msg; + integer val; + // Testcase reporting events & signals + event testcase_log_written; + event test_end; + reg [1599: 0] test_name; + reg error_detected; + + // Module for writing to log files + uart_log log (); + defparam log.testcase_name = "uart_interrupts"; + + // Log + initial + fork + begin: init_log + reg ok; + // Delay allows all other blocks in this fork - join block to execute + #1; + log.start_log(ok); + if (ok !== 1'b1) + begin + `SEVERE_ERROR("Failed to open log file(s)!"); + disable init_log; + end + testcase_init; + testcase_test; + log.end_log; + # 100; + $finish; + end + begin + forever + begin + @(test_name); + error_detected = 1'b0; + log.report_test_name(test_name); + log.verbose_test_name(test_name); + -> testcase_log_written; + end + end + begin + forever + begin + @(test_end); + if (error_detected) + begin + log.tests_failed = log.tests_failed + 1'b1; + end + else + begin + log.tests_ok = log.tests_ok + 1'b1; + log.report_test_ok; + end + -> testcase_log_written; + end + end + begin + @(severe_err_event); + error_detected = 1'b1; + -> test_end; + @(testcase_log_written); + log.report_test_failed(severe_err_msg); + if (testcase.log.free == 0) + begin + wait (testcase.log.free); + severe_err_msg = "Failed to write to log file(s)!"; + end + log.verbose_severe_err(tim, severe_err_msg); + -> testbench_log_written; + # 100; $finish; + end + begin + forever + begin + @(err_event); + error_detected = 1'b1; + -> test_end; + @(testcase_log_written); + log.report_test_failed(msg); + if (testcase.log.free == 0) + begin + `SEVERE_ERROR("Failed to write to log file(s)!"); + end + log.verbose_err(tim, msg); + -> testbench_log_written; + `PROMPT; + end + end + begin + forever + begin + @(wrn_event); + if (testcase.log.free == 0) + begin + `SEVERE_ERROR("Failed to write to log file(s)!"); + end + log.verbose_wrn(tim, msg); + -> testbench_log_written; + end + end + begin + forever + begin + @(msg_event); + if (testcase.log.free == 0) + begin + `SEVERE_ERROR("Failed to write to log file(s)!"); + end + log.verbose_msg(tim, msg); + -> testbench_log_written; + end + end + begin + forever + begin + @(val_event); + if (testcase.log.free == 0) + begin + `SEVERE_ERROR("Failed to write to log file(s)!"); + end + log.verbose_val(tim, msg, val); + -> testbench_log_written; + end + end + join + + +// Testcase (DEPENDENT) code +//########################### + + // Initialization + task testcase_init; + begin:init + test_name = "Initialization of UART."; + @(testcase_log_written); + // + testbench_utilities.do_reset; + testbench_utilities.disable_clk_generators(1, 1, 1, 1); + testbench_utilities.set_device_tx_rx_clk_divisor(32'h1000); + testbench_utilities.set_wb_clock_period(100); + testbench_utilities.enable_clk_generators(1, 1, 1, 1); + #100; + testbench_utilities.release_reset; + // + uart_wb_utilities.write_dlr(16'h1000); + uart_wb_utilities.write_ier(8'h07); + uart_wb_utilities.write_fcr(8'hC0); + uart_wb_utilities.write_lcr(8'h03); + // + uart_device_utilities.set_rx_length(8); + uart_device_utilities.disable_rx_parity; + uart_device_utilities.set_rx_second_stop_bit(0); + // + uart_device_utilities.set_tx_length(8); + uart_device_utilities.disable_tx_parity; + uart_device_utilities.correct_tx_parity; + uart_device_utilities.correct_tx_frame; + uart_device_utilities.generate_tx_glitch(0); + + -> test_end; + @(testcase_log_written); + end + endtask // testcase_init + + // Testcase + task testcase_test; + begin:test + test_name = "Interrupt test."; + @(testcase_log_written); + fork + begin: test + uart_wb_utilities.write_char(8'hAA); + @(testbench.int_aserted); + `TC_MSG("INT ASSERTED!"); + uart_wb_utilities.write_char(8'hAA); + @(testbench.int_released); + `TC_MSG("INT RELEASED!"); + @(testbench.int_aserted); + `TC_MSG("INT ASSERTED!"); + uart_wb_utilities.read_iir; + @(testbench.int_released); + `TC_MSG("INT RELEASED!"); + end + begin: wait_end + @(testbench.i_uart_device.device_received_packet); + @(testbench.i_uart_device.device_received_packet); + repeat(2) @(testbench.i_uart_device.rx_clk); + disable test; + disable wait_clk; + end + begin: wait_clk + testbench_utilities.wait_for_num_of_wb_clk(32'h450000); + disable test; + disable wait_end; + end + join + repeat (4) @(posedge testbench.wb_clk); + # 100; + + -> test_end; + @(testcase_log_written); + end + endtask // testcase_test + + +endmodule +
tags/rel_3/bench/verilog/test_cases/uart_int.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/rel_3/bench/verilog/uart_log.v =================================================================== --- tags/rel_3/bench/verilog/uart_log.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_log.v (revision 102) @@ -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 + Index: tags/rel_3/bench/verilog/uart_wb_utilities.v =================================================================== --- tags/rel_3/bench/verilog/uart_wb_utilities.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_wb_utilities.v (revision 102) @@ -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 \ No newline at end of file Index: tags/rel_3/bench/verilog/wb_master_model.v =================================================================== --- tags/rel_3/bench/verilog/wb_master_model.v (nonexistent) +++ tags/rel_3/bench/verilog/wb_master_model.v (revision 102) @@ -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 + Index: tags/rel_3/bench/verilog/uart_device_utilities.v =================================================================== --- tags/rel_3/bench/verilog/uart_device_utilities.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_device_utilities.v (revision 102) @@ -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 \ No newline at end of file Index: tags/rel_3/bench/verilog/uart_testbench_utilities.v =================================================================== --- tags/rel_3/bench/verilog/uart_testbench_utilities.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_testbench_utilities.v (revision 102) @@ -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 \ No newline at end of file Index: tags/rel_3/bench/verilog/wb_model_defines.v =================================================================== --- tags/rel_3/bench/verilog/wb_model_defines.v (nonexistent) +++ tags/rel_3/bench/verilog/wb_model_defines.v (revision 102) @@ -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] + Index: tags/rel_3/bench/verilog/uart_testbench_defines.v =================================================================== --- tags/rel_3/bench/verilog/uart_testbench_defines.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_testbench_defines.v (revision 102) @@ -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 Index: tags/rel_3/bench/verilog/uart_test.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/bench/verilog/uart_test.v =================================================================== --- tags/rel_3/bench/verilog/uart_test.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_test.v (revision 102)
tags/rel_3/bench/verilog/uart_test.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/bench/verilog/uart_device.v =================================================================== --- tags/rel_3/bench/verilog/uart_device.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_device.v (revision 102) @@ -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 Index: tags/rel_3/bench/verilog/uart_testbench.v =================================================================== --- tags/rel_3/bench/verilog/uart_testbench.v (nonexistent) +++ tags/rel_3/bench/verilog/uart_testbench.v (revision 102) @@ -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 + + Index: tags/rel_3/bench/verilog/vapi.log =================================================================== --- tags/rel_3/bench/verilog/vapi.log (nonexistent) +++ tags/rel_3/bench/verilog/vapi.log (revision 102) @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// vapi.log //// +//// //// +//// //// +//// This file is part of the "UART 16550 compatible" project //// +//// http://www.opencores.org/projects/uart16550/ //// +//// //// +//// Documentation related to this project: //// +//// http://www.opencores.org/projects/uart16550/ //// +//// //// +//// Projects compatibility: //// +//// - WISHBONE //// +//// RS232 Protocol //// +//// 16550D uart (mostly supported) //// +//// //// +//// Overview (main Features): //// +//// Device interface for testing purposes //// +//// //// +//// Known problems (limits): //// +//// //// +//// To Do: //// +//// Nothing. //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorm@opencores.org) //// +//// //// +//// Created and updated: (See log for the revision history) //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 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 $ +// +// +// +// + + +001000020 // devisor 0x32 +002000300 // rx lcr 8n1 + +// Receive +10000034a // Receive J +100000361 // Receive a +100000363 // Receive c +10000030a // Receive \n + +// Send +000000371 // Transmit q - switching to interrupt mode +100000353 // Receive S +100000377 // Receive w +10000030a // Receive \n +006000020 // wait 32 tx cycles +000000331 // Transmit 1 +000000332 // Transmit 2 +000000333 // Transmit 3 +000000334 // Transmit 4 +000000335 // Transmit 5 +000000336 // Transmit 6 +000000337 // Transmit 7 +000000338 // Transmit 8 +000000339 // Transmit 9 +000000361 // Transmit a +000000362 // Transmit b +000000363 // Transmit c +000000364 // Transmit d +000000365 // Transmit e +000000366 // Transmit f +006000040 // wait 64 tx cycles +100000331 // Receive 1 +100000332 // Receive 2 +100000333 // Receive 3 +100000334 // Receive 4 +100000335 // Receive 5 +100000336 // Receive 6 +100000337 // Receive 7 +100000338 // Receive 8 +100000339 // Receive 9 +100000341 // Receive A +100000342 // Receive B +100000343 // Receive C +100000344 // Receive D +100000345 // Receive E +100000346 // Receive F + +200000000 // Exit simulation Index: tags/rel_3/bench/verilog/readme.txt =================================================================== --- tags/rel_3/bench/verilog/readme.txt (nonexistent) +++ tags/rel_3/bench/verilog/readme.txt (revision 102) @@ -0,0 +1,111 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// readme.txt //// +//// //// +//// //// +//// This file is part of the "UART 16550 compatible" project //// +//// http://www.opencores.org/projects/uart16550/ //// +//// //// +//// Documentation related to this project: //// +//// http://www.opencores.org/projects/uart16550/ //// +//// //// +//// Projects compatibility: //// +//// - WISHBONE //// +//// RS232 Protocol //// +//// 16550D uart (mostly supported) //// +//// //// +//// Overview (main Features): //// +//// Device interface for testing purposes //// +//// //// +//// Known problems (limits): //// +//// //// +//// To Do: //// +//// Nothing. //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorm@opencores.org) //// +//// //// +//// Created and updated: (See log for the revision history) //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 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 $ +// +// +// +// + + +Following files are making an UART16550 PHY and are used for testing: + +uart_device_if_defines.v - defines related to PHY +uart_device_if_memory.v - Module for initializing PHY (reading commands from vapi.log file) +uart_device_if.v - Uart PHY with additional feature for testing +vapi.log - File with commands (expected data, data to be send, etc.) +readme.txt - This file + + + + +OPERATION: +uart_device_if.v is a uart PHY and connects to the uart_top.v. PHY takes commands from vapi.log +file. Depending on command it can: +- set a mode (5, 6, 7, 8-bit, parity, stop bits, etc.) +- set a frequency divider (dll) +- send a character +- receive a character and compare it to the expected one +- send a glitch (after a certain period of time) +- send a break +- detect a break +- Check if fifo is empty/not empty (and generate an error if expected value differs from actual) +- delay (does nothing for certain number of characters) + +On the other side of uart some kind of host must be connected that controls the phy. + +This is the structure: + + + |||||||||||||| |||||||||||||||| |||||||||||||||| + | | | | | | + | Host | <----------> | UART | <----------> | PHY | + | | | | | | + |||||||||||||| |||||||||||||||| |||||||||||||||| + + + PHY must know how host sets th UART and work in the same mode. Besides that it must know what + host is sending or expecting to receive. Operation of the PHY must be written in the vapi.log + file. + + When I was using this testing environment, I used OpenRISC1200 as a host. Everything is fully + operational. UART was also tested in hardware (on two different boards), running uCLinux in + both, interrupt and polling mode. + + \ No newline at end of file Index: tags/rel_3/bench/verilog/wb_mast.v =================================================================== --- tags/rel_3/bench/verilog/wb_mast.v (nonexistent) +++ tags/rel_3/bench/verilog/wb_mast.v (revision 102) @@ -0,0 +1,631 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE Master Model //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: wb_mast.v,v 1.1 2001-12-03 21:44:23 gorban Exp $ +// +// $Date: 2001-12-03 21:44:23 $ +// $Revision: 1.1 $ +// $Author: gorban $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: not supported by cvs2svn $ +// +// +// +// +// + +/* + +task mem_fill; + +- Fills local burst read (rd_buf[]) and write(wr_buf[]) buffers with random values. + + +task wb_wr1( 32 bit address, 4 bit byte select, 32 bit write data); + +- Performs a single WISHBONE write + + +task wb_wr4( 32 bit address, 4 bit byte select, integer delay, + 32 bit data 1, 32 bit data 2, 32 bit data 3, 32 bit data 4); + +- Performs 4 consecutive WISHBONE writes +- Strobe is deasserted between writes for 'delay' number of cycles + (This simulates wait state insertion ...) + + +task wb_wr_mult( 32 bit address, 4 bit byte select, integer delay, + integer count); + +- Simular to wb_wr4, except it pwrforms "count" number of write cycles. + The data is taken from the internal wr_bub[] memory. +- Strobe is deasserted between writes for 'delay' number of cycles + (This simulates wait state insertion ...) + + +task wb_rmw( 32 bit address, 4 bit byte select, integer delay, + integer rcount, integer wcount); + +- This task performs "rcount" read cycles, followed by wcount write cycles. +- read data is placed in to the internal rd_buf[] memory, write data is + taken from the internal wr_buf[] memory. +- Strobe is deasserted between writes for 'delay' number of cycles + (This simulates wait state insertion ...) + + +task wb_rd1( 32 bit address, 4 bit byte select, 32 bit read data); + +- Performs a single WISHBONE write + + +task wb_rd4( 32 bit address, 4 bit byte select, integer delay, + 32 bit data 1, 32 bit data 2, 32 bit data 3, 32 bit data 4); + +- Performs 4 consecutive WISHBONE reads +- Strobe is deasserted between reads for 'delay' number of cycles + (This simulates wait state insertion ...) + + +task wb_rd_mult( 32 bit address, 4 bit byte select, integer delay, + integer count); + +- Simular to wb_rd4, except it pwrforms "count" number of read cycles. + The data is read in to the internal rd_buf[] memory. +- Strobe is deasserted between reads for 'delay' number of cycles + (This simulates wait state insertion ...) + + +*/ + + +//`include "wb_model_defines.v" + +module wb_mast(clk, rst, adr, din, dout, cyc, stb, sel, we, ack, err, rty); + +input clk, rst; +output [31:0] adr; +input [31:0] din; +output [31:0] dout; +output cyc, stb; +output [3:0] sel; +output we; +input ack, err, rty; + +//////////////////////////////////////////////////////////////////// +// +// Local Wires +// + +parameter mem_size = 4096; + +reg [31:0] adr; +reg [31:0] dout; +reg cyc, stb; +reg [3:0] sel; +reg we; + +reg [31:0] rd_mem[mem_size:0]; +reg [31:0] wr_mem[mem_size:0]; +integer rd_cnt; +integer wr_cnt; + +//////////////////////////////////////////////////////////////////// +// +// Memory Logic +// + +initial + begin + adr = 32'hxxxx_xxxx; + dout = 32'hxxxx_xxxx; + cyc = 0; + stb = 0; + sel = 4'hx; + we = 1'hx; + rd_cnt = 0; + wr_cnt = 0; + #1; + $display("\nINFO: WISHBONE MASTER MODEL INSTANTIATED (%m)\n"); + end + + + +task mem_fill; + +integer n; +begin +rd_cnt = 0; +wr_cnt = 0; +for(n=0;n
tags/rel_3/doc/src/UART_spec.doc Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/doc/UART_spec.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/doc/UART_spec.pdf =================================================================== --- tags/rel_3/doc/UART_spec.pdf (nonexistent) +++ tags/rel_3/doc/UART_spec.pdf (revision 102)
tags/rel_3/doc/UART_spec.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/doc/CHANGES.txt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/rel_3/doc/CHANGES.txt =================================================================== --- tags/rel_3/doc/CHANGES.txt (nonexistent) +++ tags/rel_3/doc/CHANGES.txt (revision 102)
tags/rel_3/doc/CHANGES.txt Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/rel_3/lint/log/.keepme =================================================================== Index: tags/rel_3/lint/run/.keepme =================================================================== Index: tags/rel_3/lint/out/.keepme =================================================================== Index: tags/rel_3/lint/bin/.keepme =================================================================== Index: tags/rel_3/syn/log/.keepme =================================================================== Index: tags/rel_3/syn/run/.keepme =================================================================== Index: tags/rel_3/syn/out/.keepme =================================================================== Index: tags/rel_3/syn/src/.keepme =================================================================== Index: tags/rel_3/syn/bin/.keepme =================================================================== Index: tags/rel_3/fv/.keepme ===================================================================

powered by: WebSVN 2.1.0

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