[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 |