FPGARelated.com
Forums

UART receiver

Started by promach October 11, 2017
Hi, I am working on UART receiver. As of now, I am stucked at http://paste.ubuntu.com/25720292/ I could not find a proper hardware writing style to continue with line 14

the overall hierarchy : https://i.imgur.com/lVEtKXT.png





module sampling_strobe_generator(clk, start_detected, sampling_strobe);  // produces sampling signal for the incoming Rx

input clk, start_detected;
output reg sampling_strobe = 0;

localparam CLOCKS_PER_BIT = 5000; // number of system clock in one UART bit, or equivalently 1/9600Hz divided by 1/48MHz

reg [($clog2(CLOCKS_PER_BIT)-1) : 0] counter = 0;

always @(posedge clk)
begin
    if(start_detected)
	counter <= 0;
    else
	
end

always @(posedge clk)
begin
    counter <= counter + 1;
end

endmodule



module rx_state(clk, start_detected, sampling_strobe, data_is_available, data_is_valid, is_parity_stage);  // FSM for UART Rx

input clk, start_detected, sampling_strobe;
output reg data_is_available = 0;
output reg data_is_valid = 0;
output reg is_parity_stage = 0;

reg [3:0] state = 0;

localparam Rx_IDLE       = 4'b0000
localparam Rx_START_BIT  = 4'b0001
localparam Rx_DATA_BIT_0 = 4'b0010
localparam Rx_DATA_BIT_1 = 4'b0011
localparam Rx_DATA_BIT_2 = 4'b0100
localparam Rx_DATA_BIT_3 = 4'b0101
localparam Rx_DATA_BIT_4 = 4'b0110
localparam Rx_DATA_BIT_5 = 4'b0111
localparam Rx_DATA_BIT_6 = 4'b1000
localparam Rx_DATA_BIT_7 = 4'b1001
localparam Rx_PARITY_BIT = 4'b1010
localparam Rx_STOP_BIT   = 4'b1011

always @(posedge clk)
begin
    data_is_valid <= (state == Rx_STOP_BIT);  // so as to align with rx_error
    is_parity_stage  <= (state == Rx_PARITY_BIT);  // parity state
    data_is_available <= ((state >= Rx_DATA_BIT_0) && (state <= Rx_DATA_BIT_7)); // data states
end

always @(posedge clk)
begin
    if (sampling_strobe) begin
    case(state)
	Rx_IDLE 	: state <= (start_detected) ?  Rx_START_BIT : Rx_IDLE;

	Rx_START_BIT	: state <= Rx_DATA_BIT_0;

	Rx_DATA_BIT_0,
	Rx_DATA_BIT_1,
	Rx_DATA_BIT_2,	
	Rx_DATA_BIT_3,
	Rx_DATA_BIT_4,
	Rx_DATA_BIT_5,
	Rx_DATA_BIT_6,
	Rx_DATA_BIT_7	: state <= state + 1'b1;

	Rx_PARITY_BIT 	: state <= Rx_STOP_BIT;

	Rx_STOP_BIT 	: state <= Rx_IDLE;

	default      	: state <= Rx_IDLE;
    endcase
    end
end

endmodule
promach wrote on 10/11/2017 10:06 AM:
> Hi, I am working on UART receiver. As of now, I am stucked at http://paste.ubuntu.com/25720292/ I could not find a proper hardware writing style to continue with line 14 > > the overall hierarchy : https://i.imgur.com/lVEtKXT.png > > > > > > module sampling_strobe_generator(clk, start_detected, sampling_strobe); // produces sampling signal for the incoming Rx > > input clk, start_detected; > output reg sampling_strobe = 0; > > localparam CLOCKS_PER_BIT = 5000; // number of system clock in one UART bit, or equivalently 1/9600Hz divided by 1/48MHz > > reg [($clog2(CLOCKS_PER_BIT)-1) : 0] counter = 0; > > always @(posedge clk) > begin > if(start_detected) > counter <= 0; > else > > end > > always @(posedge clk) > begin > counter <= counter + 1; > end > > endmodule > > > > module rx_state(clk, start_detected, sampling_strobe, data_is_available, data_is_valid, is_parity_stage); // FSM for UART Rx > > input clk, start_detected, sampling_strobe; > output reg data_is_available = 0; > output reg data_is_valid = 0; > output reg is_parity_stage = 0; > > reg [3:0] state = 0; > > localparam Rx_IDLE = 4'b0000 > localparam Rx_START_BIT = 4'b0001 > localparam Rx_DATA_BIT_0 = 4'b0010 > localparam Rx_DATA_BIT_1 = 4'b0011 > localparam Rx_DATA_BIT_2 = 4'b0100 > localparam Rx_DATA_BIT_3 = 4'b0101 > localparam Rx_DATA_BIT_4 = 4'b0110 > localparam Rx_DATA_BIT_5 = 4'b0111 > localparam Rx_DATA_BIT_6 = 4'b1000 > localparam Rx_DATA_BIT_7 = 4'b1001 > localparam Rx_PARITY_BIT = 4'b1010 > localparam Rx_STOP_BIT = 4'b1011 > > always @(posedge clk) > begin > data_is_valid <= (state == Rx_STOP_BIT); // so as to align with rx_error > is_parity_stage <= (state == Rx_PARITY_BIT); // parity state > data_is_available <= ((state >= Rx_DATA_BIT_0) && (state <= Rx_DATA_BIT_7)); // data states > end > > always @(posedge clk) > begin > if (sampling_strobe) begin > case(state) > Rx_IDLE : state <= (start_detected) ? Rx_START_BIT : Rx_IDLE; > > Rx_START_BIT : state <= Rx_DATA_BIT_0; > > Rx_DATA_BIT_0, > Rx_DATA_BIT_1, > Rx_DATA_BIT_2, > Rx_DATA_BIT_3, > Rx_DATA_BIT_4, > Rx_DATA_BIT_5, > Rx_DATA_BIT_6, > Rx_DATA_BIT_7 : state <= state + 1'b1; > > Rx_PARITY_BIT : state <= Rx_STOP_BIT; > > Rx_STOP_BIT : state <= Rx_IDLE; > > default : state <= Rx_IDLE; > endcase > end > end > > endmodule
I believe the module sampling_strobe_generator is intended to provide a strobe aligned to the center of the bit. The question I have is what is the specification of the signal "start_detected"? Is that aligned to the center of the start bit? Where are you rejecting false start bits? -- Rick C Viewed the eclipse at Wintercrest Farms, on the centerline of totality since 1998