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

Subversion Repositories uart2bus

[/] [uart2bus/] [trunk/] [verilog/] [bench/] [uart_tasks.v] - Rev 12

Compare with Previous | Blame | View Log

//------------------------------------------------------------------------------
// uart tasks:
//		send_serial		serial transmitter 
// 		get_serial		serial receiver 
//
//------------------------------------------------------------------------------
 
/*  Serial Parameters used for send_serial task and its callers. */
`define PARITY_OFF		1'b0
`define PARITY_ON		1'b1
`define PARITY_ODD		1'b0
`define PARITY_EVEN		1'b1
`define NSTOPS_1		1'b0
`define NSTOPS_2		1'b1
`define BAUD_115200		3'b000
`define BAUD_38400		3'b001
`define BAUD_28800		3'b010
`define BAUD_19200		3'b011
`define BAUD_9600		3'b100
`define BAUD_4800		3'b101
`define BAUD_2400		3'b110
`define BAUD_1200		3'b111
`define NBITS_7			1'b0
`define NBITS_8			1'b1
// constants for status from get_serial task 
`define RECEIVE_RESULT_OK			4'b1000 
`define RECEIVE_RESULT_FALSESTART	4'b0001 
`define RECEIVE_RESULT_BADPARITY	4'b0010 
`define RECEIVE_RESULT_BADSTOP		4'b0100 
 
// uart tasks global interfaces signals 
reg serial_out;		// transmit serial output 
reg serial_in;		// receive serial input 
reg [7:0] get_serial_data;		// data received from serial 
reg [7:0] get_serial_status;	// status of receive operation 
 
//------------------------------------------------------------------------------
// uart transmit task 
// 
// usage:
//		send_serial (data, baud_rate, parity_type, parity_on, stop_bits_num, 
//														data_bit_num, baud_error);
// where:
//		data			data character for transmission 
//		parity_type		this is a flag indicating that parity should be even 
//						(either 'PARITY_ODD or 'PARITY_EVEN)
//		parity_on		indicates that the parity is used 
//						(either 'PARITY_OFF or 'PARITY_ON)
//		stop_bits_num	number of stop bits (either NSTOPS_1 or NSTOPS_2)
//		data_bit_num	number of data bits (either NBITS_7 or NBITS_8)
//		baud_error		baud error in precentage (-5 is -5%)
// 
 
task send_serial;
// task input parameters 
input [7:0] inputchar;
input baud;
input paritytype;
input parityenable;
input nstops;
input nbits;
input baud_error_factor;
// internal registers 
reg       nbits;
reg       parityenable;
reg       paritytype;
reg [1:0] baud;
reg       nstops;
integer		baud_error_factor;  // e.g. +5 means 5% too fast and -5 means 5% too slow
reg	[7:0] 	char;
reg [7:0]	disp_char;
reg         parity_bit;
integer     bit_time;
integer		num_of_bits;
// task implementation 
begin 
	char = inputchar;
	parity_bit = 1'b0;
	// calculate bit time from input baud rate - this assumes a simulation resolution of 1ns 
	case (baud)
		`BAUD_115200: bit_time = 1000000000/(115200 + 1152*baud_error_factor);
//	        `BAUD_115200: bit_time = 40000000000/(115200 + 1152*baud_error_factor);
		`BAUD_38400:  bit_time = 1000000000/(38400 + 384*baud_error_factor);
		`BAUD_28800:  bit_time = 1000000000/(28800 + 288*baud_error_factor);
		`BAUD_19200:  bit_time = 1000000000/(19200 + 192*baud_error_factor);
		`BAUD_9600:   bit_time = 1000000000/(9600 + 96*baud_error_factor);
		`BAUD_4800:   bit_time = 1000000000/(4800 + 48*baud_error_factor);
		`BAUD_2400:   bit_time = 1000000000/(2400 + 24*baud_error_factor);
		`BAUD_1200:   bit_time = 1000000000/(1200 + 12*baud_error_factor);
	endcase   
 
	// display info 
	disp_char = (char >= 8'h20) ? char : 8'hb0;
	$display ("Sending character 0x%h (\"%c\"), at %0d baud (err=%0d), %0d bits, %0s parity, %0d stops",
		(nbits == `NBITS_7) ? (char & 8'h7f) : char,
		(nbits == `NBITS_7) ? (disp_char & 8'h7f) : disp_char,
		1000000000/bit_time,
		baud_error_factor,
		(nbits == `NBITS_7) ? 7 : 8,
		(parityenable == `PARITY_OFF) ? "NONE" : (paritytype == `PARITY_EVEN) ? "EVEN" : "ODD",
		(nstops == `NSTOPS_1) ? 1 : 2
	);
 
	// Start bit
	serial_out = 1'b0;   // Start bit.
	#(bit_time);
 
	// Output data bits
	num_of_bits = (nbits == `NBITS_7) ? 7 : 8;
	repeat (num_of_bits) 
	begin
		serial_out = char[0];
		#(bit_time);
		char = {1'b0, char[7:1]};
	end
 
	// check if parity is enabled 
	if (parityenable == `PARITY_ON) begin
		parity_bit = (nbits == `NBITS_7) ? ^inputchar[6:0] : ^inputchar[7:0];
		// even parity
		if (paritytype == `PARITY_ODD) 
			parity_bit = ~parity_bit; 
 
		serial_out = parity_bit;
		#(bit_time);
	end
 
	// Stop bit.
	serial_out = 1'b1;   
	#(bit_time);
	// Second stop bit
	if (nstops) 
		#(bit_time);
end
endtask
 
//------------------------------------------------------------------------------
// uart receive task 
// 
// usage:
//		get_serial (baud_rate, parity_type, parity_on, stop_bits_num, data_bit_num);
// where:
//		data			data character for transmission 
//		parity_type		this is a flag indicating that parity should be even 
//						(either 'PARITY_ODD or 'PARITY_EVEN)
//		parity_on		indicates that the parity is used 
//						(either 'PARITY_OFF or 'PARITY_ON)
//		stop_bits_num	number of stop bits (either NSTOPS_1 or NSTOPS_2)
//		data_bit_num	number of data bits (either NBITS_7 or NBITS_8)
// 
task get_serial;
// input parameters 
input baud;
input paritytype;
input parityenable;
input nstops;
input nbits;
// internal registers 
reg       nbits;
reg       parityenable;
reg       paritytype;
reg [1:0] baud;
reg       nstops;
integer     bit_time;
reg         expected_parity;
integer		num_of_bits;
// task implementation 
begin 
	// init receive globals 
	get_serial_status = 0;
	get_serial_data = 0;
 
	// calculate bit time from input baud rate - this assumes a simulation resolution of 1ns 
	case (baud)
		`BAUD_115200: bit_time = 1000000000/115200;
		`BAUD_38400:  bit_time = 1000000000/38400;
		`BAUD_28800:  bit_time = 1000000000/28800;
		`BAUD_19200:  bit_time = 1000000000/19200;
		`BAUD_9600:   bit_time = 1000000000/9600;
		`BAUD_4800:   bit_time = 1000000000/4800;
		`BAUD_2400:   bit_time = 1000000000/2400;
		`BAUD_1200:   bit_time = 1000000000/1200;
	endcase   
 
	// Assume OK until bad things happen.
	get_serial_status = `RECEIVE_RESULT_OK;  
 
	// wait for start bit edge 
	@(negedge serial_in);  
 
	// wait till center of start bit 
	#(bit_time/2);  
 
	// make sure its really a start bit
	if (serial_in != 0) 
		get_serial_status = get_serial_status | `RECEIVE_RESULT_FALSESTART;
	else 
	begin
		// get all the data bits (7 or 8) 
		num_of_bits = (nbits == `NBITS_7) ? 7 : 8;
		repeat (num_of_bits) 
		begin 
			// wait till center 
			#(bit_time);  
			// sample a data bit
			get_serial_data = {serial_in, get_serial_data[7:1]};
		end
 
		// If we are only expecting 7 bits, go ahead and right-justify what we have
		if (nbits == `NBITS_7)
			get_serial_data = {1'b0, get_serial_data[7:1]};
 
		// wait for next bit to start 
		#(bit_time);
 
 		// now, we have either a parity bit, or a stop bit
 		if (parityenable == `PARITY_ON) begin
 			if (paritytype == `PARITY_EVEN)
 				expected_parity = (nbits == `NBITS_7) ? (^get_serial_data[6:0]) :            
 															(^get_serial_data[7:0]);
 			else
 				expected_parity = (nbits == `NBITS_7) ? (~(^get_serial_data[6:0])) :  
 															(~(^get_serial_data[7:0]));
 
 			if (expected_parity != serial_in)
 				get_serial_status = get_serial_status | `RECEIVE_RESULT_BADPARITY;
 		end
 		// wait for either 1 or 2 stop bits
 		else begin
 			// this is a stop bit.
 			if (serial_in != 1)
 				get_serial_status = get_serial_status | `RECEIVE_RESULT_BADSTOP;
 			else
 				// that was cool.  if 2 stops, then do this again
 				if (nstops) 
 				begin
 					#(bit_time);
 					if (serial_in != 1)
 						get_serial_status = get_serial_status | `RECEIVE_RESULT_BADSTOP;
 				end
 		end
	end
end
endtask
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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