UART(Universal Asynchronous Receiver/Transmitter)는 병렬데이터를 직렬로 전환하여 전송하는 하드웨어다. wire를 통해 한번에 한 byte씩 LSB부터 데이터를 전송한다.
UART는 이름과 같이 Asynchronous이므로 두 디바이스의 속도(baudrate), data수, parity, stop등의 setting이 같아야 정상적인 통신이 가능하다.
start bit부터 stop bit까지를 1 frame이라고 한다.
프로토콜을 총 4가지 상태로 나눌 수 있다.
IDEL : 전송이 시작되지 않은 휴식상태, logic = 1
Start : 데이터 전송의 시작을 알리며, logic = 0으로 떨어진다.
Data : 8bit 데이터가 전송된다.
Stop : 데이터 전송 끝을 알린다, logic = 1
송신단은 baudrate와 프로토콜에 맞춰 wire에 정보를 전달하고, 수신단은 start를 감지 후 첫번째 bit의 중간까지 기다린 후 데이터를 sampling하기 시작하여 8bit의 데이터를 읽을 때까지 송신단과 속도를 맞춰 wire의 정보를 읽는다.
FPGA내부 clk을 분주하여 UART에서 사용할 Baud rate를 만든다.
baudrate : 9600
16 over sampling
baudrate 9600을 16 over sampling하는 tick신호를 만든다.
module baudrate_generator (
input clk,
input reset,
output br_tick
);
// "상수값을 계산할 때" 사용하는 operator는 하드웨어가 만들어지지 않는다.
reg [$clog2(100_000_000 / 9600 / 16) - 1:0] counter_reg, counter_next;
reg tick_reg, tick_next;
assign br_tick = tick_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
counter_reg <= 0;
tick_reg <= 1'b0;
end else begin
counter_reg <= counter_next;
tick_reg <= tick_next;
end
end
always @(*) begin
counter_next = counter_reg;
if (counter_reg == (100_000_000 / 9600 / 16) - 1) begin
//if (counter_reg == 3) begin // for simulation
counter_next = 0;
tick_next = 1'b1;
end else begin
counter_next = counter_reg + 1;
tick_next = 1'b0;
end
end
endmodule
State Diagram
ASM Chart
start신호와 병렬 데이터가 입력되면 baud rate에 맞춰 직렬로 데이터를 전송한다.
전반적인 형태는 Transmitter와 유사하다.
차이점
start 입력이 없으며, rx신호의 1->0으로 시작을 감지한다.
START state범위를 16 sampling값의 절반인 8만큼 가져가도록하여 data를 sampling할 때 data의 중간 값을 읽도록 만든다.