TX

 

TX Block 부분은 Parallel로 받은 Data를 다시 Serial로 변경시켜서 출력하는 Block입니다.

저번에 제작한 FIFO Block에서 나온 Output을 받아 TX를 제작하겠습니다.

TX Blck Diagram

TX에서도 상태 변화를 FSM(Finite State Machine)을 사용하여 구현하겠습니다.

TX FSM


uart_tx.v code

`timescale 1ns / 1ps

module uart_tx(
    input [7:0] DATA,                   // output from the FIFO
    input START,                        //  ~Empty signal from FIFO
    input RST,
    input CLK,
    output reg TXD                          // Serial output. It's equal to RXDin
    );
    
localparam [1:0] idle = 2'b00,         //FSM state component                 
                               start = 2'b01,
                               tx_send = 2'b10,
                                stop = 2'b11;
reg [3:0] curr_state, next_state;       //FSM state Register
reg [3:0] over_sample_cnt, bit_cnt;
wire over_sample_cnt_done, bit_cnt_done;
wire parity;
wire baud_x16_en;
reg [7:0] tx_data_in;
wire [8:0] tx_data = {parity, tx_data_in};

always @ (posedge CLK) begin
if(START)
        tx_data_in <= DATA;
end

always @ (posedge CLK) begin  // Check the state per 1 clk, change to the next state
if (RST)
        curr_state <= idle;
else
        curr_state <= next_state;
end

always @ (curr_state, START, over_sample_cnt_done, bit_cnt_done) begin          //FSM
case (curr_state)
        idle :          // when START be a '1' in idle state, Change curr_state to start
                if(START)
                        next_state = start;
                else    // else maintain the idle
                        next_state = idle;
        start :         // when 'over_sample_cnt_done' be a '1' in start state, Change curr_state to tx_send
                if(over_sample_cnt_done)
                        next_state = tx_send;
                else   // else maintain the start
                        next_state = start;
        tx_send :         // when 'over_sample_cnt_done & bit_cnt_done' be a '1' in tx_send state, Change curr_state to stop
                if(over_sample_cnt_done && bit_cnt_done)
                        next_state = stop;
                else   // else maintain the tx_send
                        next_state = tx_send;
        stop :         // when 'over_sample_cnt_done' be a '1' in stop state, Change curr_state to idle 
                if(over_sample_cnt_done)
                        next_state = idle;
                else   // else maintain the stop
                        next_state = stop;
        default : next_state = idle;
        endcase
end

// The part of making over_sample_cnt
always @ (posedge CLK) begin
if (curr_state == idle)
        over_sample_cnt <= 5'd15;
else if (baud_x16_en)
        over_sample_cnt <= over_sample_cnt -1;
end
assign over_sample_cnt_done = (over_sample_cnt == 4'd0) & baud_x16_en;

//The part of making bit_cnt
always @ (posedge CLK) begin
if (curr_state != tx_send)
        bit_cnt <= 4'd0;
else if (over_sample_cnt_done)
        bit_cnt <= bit_cnt + 1;
end
assign bit_cnt_done = over_sample_cnt_done & (bit_cnt == 4'd8);

//make a parity          
assign parity = tx_data[7:0];

//Parallel to Serial (TXD)
always @ (curr_state, bit_cnt) begin
        if (curr_state == idle || curr_state == stop)
                TXD = 1'b1;
        else if (curr_state == start)
                TXD = 1'b0;
        else
                TXD = tx_data[bit_cnt];
end

//instance the uart_baud_gen
uart_baud_gen baud_gen_10 (
        .RST    (RST),
        .CLK    (CLK),
        .BAUD_X16_EN    (baud_x16_en)
);

endmodule

 

 


uart_top.v code

`timescale 1ns / 1ps

module uart_top(
    input RST,
    input CLK,
    input RXD,
    output [6:0] AN,
    output CA,
    output PAR_ERR,
    output FRM_ERR,
    output TXD
    );

wire    [7:0]   rx_data;
wire rx_data_rdy, empty;
wire    [7:0] dout;
reg     [7:0] dout_reg;

always @ (posedge CLK) begin
        if (~empty)
        dout_reg <= dout;
        end

uart_rx uart_rx_0 (
    .RST        (RST),
    .CLK        (CLK),
    .RXD        (RXD),
    .RX_DATA    (rx_data),
    .RX_DATA_RDY    (rx_data_rdy),
    .FRM_ERR    (FRM_ERR),
    .PARITY_ERR (PAR_ERR)
    );    
    
my_fifo fifo_0(
    .RST        (RST),
    .CLK        (CLK),
    .DIN        (rx_data),
    .WR_EN      (rx_data_rdy),
    .FULL       (FULL),
    .DOUT       (dout),
    .RD_EN      (~empty),
    .EMPTY      (empty)
    );
    
display_inf disp_0 (
    .RST            (RST),
    .CLK            (CLK),      // 125 Mhz
    .NUM_1S         (dout_reg [3:0]),
    .NUM_10S        (dout_reg [7:4]),
    .CA             (CA),
    .AN             (AN)
    );    
    
uart_tx uart_tx_0 (
        .RST    (RST),
        .CLK    (CLK),
        .START  (~empty),
        .DATA    (dout),
        .TXD    (TXD)
);




endmodule

가장 아래에 tx부분을 추가하여  module들을 연결해 주었습니다.

uart_top logic schematic

 

이렇게 FIFO와 Baud_x16_gen 모듈의 값에 따른 FSM을 구현한 TX module을 제작하여, 기존 uart에 연결하는 과정까지 마무리하였습니다