data/full_repos/permissive/476477303/verilog/rtl/Peripherals/UART/UART_rx.v
data/verilator_xmls/272f508e-57e8-4b0b-8cb6-104099b0fc32.xml
module UART_rx
	#(
		parameter CLOCK_SCALE_BITS = 16
	)(
		input wire clk,
		input wire rst,
		input wire[CLOCK_SCALE_BITS-1:0] cyclesPerBit,
		input wire rx,
		output wire [7:0] dataOut,
    	output wire dataAvailable
    );

	localparam STATE_IDLE		= 2'b00;
	localparam STATE_WAIT_HALF 	= 2'b01;
	localparam STATE_WAIT_FULL 	= 2'b10;
	localparam STATE_WAIT_HIGH 	= 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 newData = 1'b0;

	wire[CLOCK_SCALE_BITS-1:0] halfBitCounterValue = { 1'b0, cyclesPerBit[CLOCK_SCALE_BITS-1:1] };

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


			case (state)
				STATE_IDLE: begin
					bitCounter = 3'b0;
					delayCounter = {CLOCK_SCALE_BITS{1'b0}};
					if (!rx) state = STATE_WAIT_HALF;
				end

				STATE_WAIT_HALF: begin
					if (nextDelayCounter == halfBitCounterValue) begin						
						delayCounter = 0;
						state = STATE_WAIT_FULL;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_WAIT_FULL: begin
					if (nextDelayCounter == cyclesPerBit) begin
						savedData = {rx, savedData[7:1]};
						delayCounter = 0;
						if (bitCounter == 3'h7) begin
							state = STATE_WAIT_HIGH;
							newData = 1'b1;
						end else bitCounter = bitCounter + 1;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_WAIT_HIGH: begin
					 if (rx) state = STATE_IDLE;
				end

				default: state = STATE_IDLE;				
			endcase
		end
	end

	assign dataOut = savedData;
	assign dataAvailable = newData;
endmodule
module UART_rx
	#(
		parameter CLOCK_SCALE_BITS = 16
	)(
		input wire clk,
		input wire rst,
		input wire[CLOCK_SCALE_BITS-1:0] cyclesPerBit,
		input wire rx,
		output wire [7:0] dataOut,
    	output wire dataAvailable
    );


	localparam STATE_IDLE		= 2'b00;
	localparam STATE_WAIT_HALF 	= 2'b01;
	localparam STATE_WAIT_FULL 	= 2'b10;
	localparam STATE_WAIT_HIGH 	= 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 newData = 1'b0;

	wire[CLOCK_SCALE_BITS-1:0] halfBitCounterValue = { 1'b0, cyclesPerBit[CLOCK_SCALE_BITS-1:1] };

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


			case (state)
				STATE_IDLE: begin
					bitCounter = 3'b0;
					delayCounter = {CLOCK_SCALE_BITS{1'b0}};
					if (!rx) state = STATE_WAIT_HALF;
				end

				STATE_WAIT_HALF: begin
					if (nextDelayCounter == halfBitCounterValue) begin						
						delayCounter = 0;
						state = STATE_WAIT_FULL;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_WAIT_FULL: begin
					if (nextDelayCounter == cyclesPerBit) begin
						savedData = {rx, savedData[7:1]};
						delayCounter = 0;
						if (bitCounter == 3'h7) begin
							state = STATE_WAIT_HIGH;
							newData = 1'b1;
						end else bitCounter = bitCounter + 1;
					end else begin
						delayCounter = nextDelayCounter;
					end
				end

				STATE_WAIT_HIGH: begin
					 if (rx) state = STATE_IDLE;
				end

				default: state = STATE_IDLE;				
			endcase
		end
	end

	assign dataOut = savedData;
	assign dataAvailable = newData;
endmodule