본문 바로가기

원s/FPGA

[DE2-115] Lab.5-2: UART Receiver

[UART : Universal Asynchronous Receiver-Transmitter]

 

DE2-115 보드를 이용하여 시리얼 통신을 실습한다.  

 

 

[rs232.v]

UART Receiver 를 Verilog 로 추가 기술한다. 

더보기
/////----------------------------------------/////
module rs232(
    input               clk, 
    input               rst_n,
	
	input				rx,   
	output	reg	[7:0]	dout, 
    output  reg         rdy, 
	
    input               tx_en, 
    output              tx,
    input       [7:0]   din
);


    // 50Mhz / 115200 = 434.0
    parameter	bit_rate = 434; 
    parameter	bit_boundary = 217; 
    
    reg		[15:0]  rx_bf; 
    reg		[8:0]   rx_value; 
    reg		[1:0]   rx_state; 
    reg		[8:0]   rx_cnt; 
    reg		[2:0]   rx_data_cnt; 
    reg		[7:0]   rx_data; 
    reg		[7:0]   rx_data_bf; 
/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_state	<= 2'b00; 
        end
        else begin
            case (rx_state)
                2'b00	: begin
                    if (rx_bf == 16'h0000)
                        rx_state	<= 2'b01; 
                end
                2'b01	: begin
                    if (rx_cnt == bit_rate)
                        rx_state	<= 2'b10; 
                end
                2'b10	: begin
                    if (rx_cnt == bit_rate && rx_data_cnt == 3'b111)
                        rx_state	<= 2'b11; 	
                end
                2'b11	: begin
                    if (rx_cnt == 9'h40)
                        rx_state	<= 2'b00; 
                end
            endcase 
        end
    end

/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_bf	<= 16'hffff; 
        end
        else begin
            rx_bf	<= {rx, rx_bf[15:1]}; 
        end
    end
	
/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_cnt	<= 9'd0; 
        end
        else begin
            if (rx_state == 2'b00 || rx_cnt == bit_rate)
                rx_cnt	<= 9'd0;
            else
                rx_cnt	<= rx_cnt + 1'b1;
        end
    end
	
/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_value	<= 9'd0; 
        end
        else begin
            if (rx_state == 2'b10) begin
                if (rx_cnt == bit_rate)
                    rx_value	<= 9'd0; 
                else
                    rx_value	<= rx_value + rx_bf[0]; 
            end
            else begin
                rx_value	<= 9'd0; 
            end	 
        end
    end	

/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_data_cnt	<= 3'd0; 
        end
        else begin
            if (rx_state == 2'b10) begin
                if (rx_cnt == bit_rate) 
                    rx_data_cnt	<= rx_data_cnt + 1'b1;
            end
            else begin
                rx_data_cnt	<= 3'd0;
            end 
        end
    end

/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_data_bf	<= 8'd0; 
        end
        else begin
            if (rx_state == 2'b10) begin
                if (rx_cnt == bit_rate) begin
                    if (rx_value >= bit_boundary)
                        rx_data_bf	<= {1'b1, rx_data_bf[7:1]}; 
                    else
                        rx_data_bf	<= {1'b0, rx_data_bf[7:1]};
                end
            end
            else if (rx_state == 2'b00) begin
                rx_data_bf	<= 8'd0; 
            end 
        end
    end

/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            rx_data	<= 8'd0; 
        end
        else begin
            if (rx_state == 2'b11) 
                rx_data	<= rx_data_bf; 
        end
    end
	
/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            dout	<= 8'b0; 
            rdy     <= 1'b0; 
        end
        else begin
            if (rx_state == 2'b11 && rx_cnt == 9'h1) begin
                dout	<= rx_data; 
                rdy     <= 1'b1; 
            end
            else begin 
                rdy     <= 1'b0; 
            end
        end
    end


    reg     [1:0]       tx_state; 
    reg     [8:0]       tx_cnt; 
    reg     [2:0]       tx_data_cnt; 
    reg     [7:0]       tx_data; 
    reg                 txd; 			
/////----------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            tx_state	<= 2'b00; 
        end
        else begin
            case (tx_state)
                2'b00	: begin
                    if (tx_en == 1'b1)
                        tx_state	<= 2'b01; 
                end
                2'b01	: begin
                    if (tx_cnt == bit_rate)
                        tx_state	<= 2'b10; 
                end
                2'b10	: begin
                    if (tx_cnt == bit_rate && tx_data_cnt == 3'b111)
                        tx_state	<= 2'b11; 	
                end
                2'b11	: begin
                    if (tx_cnt == bit_boundary)
                        tx_state	<= 2'b00; 
                end
            endcase 
        end
    end

/////----------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            tx_cnt	<= 9'd0; 
        end
        else begin
            if (tx_state == 2'b00 || tx_cnt == bit_rate)
                tx_cnt	<= 9'd0;
            else
                tx_cnt	<= tx_cnt + 1'b1;
        end
    end

/////----------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            tx_data_cnt	<= 3'd0; 
        end
        else begin
            if (tx_state == 2'b10) begin
                if (tx_cnt == bit_rate) 
                    tx_data_cnt	<= tx_data_cnt + 1'b1;
            end
            else begin
                tx_data_cnt	<= 3'd0;
            end 
        end
    end

/////--------------------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            tx_data	<= 8'd0; 
        end
        else begin
            if (tx_state == 2'b00 && tx_en == 1) 
                tx_data	<= din; 
        end
    end


    assign tx = txd;
/////----------------------------------------/////
    always @(posedge clk, negedge rst_n) begin
        if (rst_n == 0) begin
            txd	<= 1'b1; 
        end
        else begin
            if (tx_state == 2'b00) begin 
                txd	<= 1'b1; 
            end
            else if (tx_state == 2'b01) begin 
                txd	<= 1'b0; 
            end
            else if (tx_state == 2'b10) begin 
                case (tx_data_cnt)
                    3'd0	: txd	<= tx_data[0]; 
                    3'd1	: txd	<= tx_data[1]; 
                    3'd2	: txd	<= tx_data[2]; 
                    3'd3	: txd	<= tx_data[3]; 
                    3'd4	: txd	<= tx_data[4]; 
                    3'd5	: txd	<= tx_data[5]; 
                    3'd6	: txd	<= tx_data[6]; 
                    3'd7	: txd	<= tx_data[7]; 
                endcase
            end
            else begin
                txd	<= 1'b1; 
            end
        end
    end

endmodule

[Pin Assign]

 

[Test Result]

이를 합성 후 출력결과를 시리얼 모니터로 확인한다. 

 

'원s > FPGA' 카테고리의 다른 글

[Quartus] RTL Simulation  (0) 2021.04.04
[Quartus] IP Catalog  (0) 2021.04.03
[DE2-115] Lab.5-1: UART transmitter  (0) 2020.07.25
[DE2-115] Lab.4-2: ASCII Decoder  (0) 2020.07.19