data/full_repos/permissive/476477303/verilog/rtl/Peripherals/UART/UART_tx.v
data/verilator_xmls/06f19338-63cb-45dc-9386-ed506b20d284.xml
module UART_tx
	#(
		parameter CLOCK_SCALE_BITS = 16
	)(
		input wire clk,
		input wire rst,
		input wire[CLOCK_SCALE_BITS-1:0] cyclesPerBit,
		output wire tx,
		input wire blockTransmition,
    	output reg busy,
    	input wire [7:0] dataIn,
    	input wire dataAvailable
    );
	
	localparam STATE_IDLE		= 2'b00;
	localparam STATE_START_BIT 	= 2'b01;
	localparam STATE_DATA 		= 2'b10;
	localparam STATE_STOP_BIT 	= 2'b11;

	reg[1:0] state = STATE_IDLE;
	reg[CLOCK_SCALE_BITS-1:0] delayCounter = {CLOCK_SCALE_BITS{1'b0}};
	wire[CLOCK_SCALE_BITS-1:0] nextDelayCounter = delayCounter + 1;
		
	reg[2:0] bitCounter = 3'b0;
	reg[7:0] savedData = 8'b0;
	reg outputBuffer = 1'b0;

	always @(posedge clk) begin
		if (rst) begin
			state = STATE_IDLE;
			delayCounter = {CLOCK_SCALE_BITS{1'b0}};
			bitCounter = 3'b0;
			savedData = 8'b0;
			outputBuffer = 1'b1;
		end else begin
			busy = 1'b1;
			

			case (state)
				STATE_IDLE: begin
					outputBuffer = 1'b1;

					if (!blockTransmition) begin
						busy = 1'b0;
						delayCounter = {CLOCK_SCALE_BITS{1'b0}};
						bitCounter = 3'b0;

						if (dataAvailable) begin
							savedData = dataIn;
							state = STATE_START_BIT;
						end
					end
				end

				STATE_START_BIT: begin
					outputBuffer = 1'b0;

					if (nextDelayCounter == cyclesPerBit) begin
						delayCounter = 0;
						state = STATE_DATA;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_DATA: begin
					outputBuffer = savedData[bitCounter];

					if (nextDelayCounter == cyclesPerBit) begin
						delayCounter = 0;
						if (bitCounter == 3'h7) state = STATE_STOP_BIT;
						else bitCounter = bitCounter + 1;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_STOP_BIT: begin
					outputBuffer = 1'b1;

					if (nextDelayCounter == cyclesPerBit) begin
						state = STATE_IDLE;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end
				
				default: state = STATE_IDLE;				
			endcase
		end
	end

	assign tx = outputBuffer;

endmodule
module UART_tx
	#(
		parameter CLOCK_SCALE_BITS = 16
	)(
		input wire clk,
		input wire rst,
		input wire[CLOCK_SCALE_BITS-1:0] cyclesPerBit,
		output wire tx,
		input wire blockTransmition,
    	output reg busy,
    	input wire [7:0] dataIn,
    	input wire dataAvailable
    );

	
	localparam STATE_IDLE		= 2'b00;
	localparam STATE_START_BIT 	= 2'b01;
	localparam STATE_DATA 		= 2'b10;
	localparam STATE_STOP_BIT 	= 2'b11;

	reg[1:0] state = STATE_IDLE;
	reg[CLOCK_SCALE_BITS-1:0] delayCounter = {CLOCK_SCALE_BITS{1'b0}};
	wire[CLOCK_SCALE_BITS-1:0] nextDelayCounter = delayCounter + 1;
		
	reg[2:0] bitCounter = 3'b0;
	reg[7:0] savedData = 8'b0;
	reg outputBuffer = 1'b0;

	always @(posedge clk) begin
		if (rst) begin
			state = STATE_IDLE;
			delayCounter = {CLOCK_SCALE_BITS{1'b0}};
			bitCounter = 3'b0;
			savedData = 8'b0;
			outputBuffer = 1'b1;
		end else begin
			busy = 1'b1;
			

			case (state)
				STATE_IDLE: begin
					outputBuffer = 1'b1;

					if (!blockTransmition) begin
						busy = 1'b0;
						delayCounter = {CLOCK_SCALE_BITS{1'b0}};
						bitCounter = 3'b0;

						if (dataAvailable) begin
							savedData = dataIn;
							state = STATE_START_BIT;
						end
					end
				end

				STATE_START_BIT: begin
					outputBuffer = 1'b0;

					if (nextDelayCounter == cyclesPerBit) begin
						delayCounter = 0;
						state = STATE_DATA;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_DATA: begin
					outputBuffer = savedData[bitCounter];

					if (nextDelayCounter == cyclesPerBit) begin
						delayCounter = 0;
						if (bitCounter == 3'h7) state = STATE_STOP_BIT;
						else bitCounter = bitCounter + 1;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_STOP_BIT: begin
					outputBuffer = 1'b1;

					if (nextDelayCounter == cyclesPerBit) begin
						state = STATE_IDLE;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end
				
				default: state = STATE_IDLE;				
			endcase
		end
	end

	assign tx = outputBuffer;

endmodule