?? uart_tx_ctl.v
字號:
//-----------------------------------------------------------------------------// // Copyright (c) 2009 Xilinx Inc.//// Project : Programmable Wave Generator// Module : uart_tx_ctl.v// Parent : uart_tx// Children : none//// Description: // UART transmit controller// Implements the state machines for doing RS232 transmission.//// Whenever a character is ready for transmission (as indicated by the// empty signal from the character FIFO), this module will transmit the// character.//// The basis of this design is a simple state machine. When in IDLE, it// waits for the character FIFO to indicate that a character is available,// at which time, it immediately starts transmition. It spends 16// baud_x16_en periods in the START state, transmitting the START// condition (1'b0), then tranisitions to the DATA state, where it sends// the 8 data bits (LSbit first), each lasting 16 baud_x16_en periods, and// finally going to the STOP state for 16 periods, where it transmits the// STOP value (1'b1).//// On the last baud_x16_en period of the last data bit (in the DATA// state), it issues the POP signal to the character FIFO. Since the SM is// only enabled when baud_x16_en is asserted, the resulting pop signal// must then be ANDed with baud_x16_en to ensure that only one character// is popped at a time. //// On the last baud_x16_en period of the STOP state, the empty indication// from the character FIFO is inspected; if asserted, the SM returns to// the IDLE state, otherwise it transitions directly to the START state to// start the transmission of the next character.//// There are two internal counters - one which counts off the 16 pulses of// baud_x16_en, and a second which counts the 8 bits of data.//// The generation of the output (txd_tx) follows one complete baud_x16_en// period after the state machine and other internal counters.//// Parameters:// None//// Local Parameters://// Notes : //// Multicycle and False Paths// All flip-flops within this module share the same chip enable, generated// by the Baud rate generator. Hence, all paths from FFs to FFs in this// module are multicycle paths.//`timescale 1ns/1psmodule uart_tx_ctl ( input clk_tx, // Clock input input rst_clk_tx, // Active HIGH reset - synchronous to clk_tx input baud_x16_en, // 16x bit oversampling pulse input char_fifo_empty, // Empty signal from char FIFO (FWFT) input [7:0] char_fifo_dout, // Data from the char FIFO output char_fifo_rd_en, // Pop signal to the char FIFO output reg txd_tx // The transmit serial signal);//***************************************************************************// Parameter definitions//*************************************************************************** // State encoding for main FSM localparam IDLE = 2'b00, START = 2'b01, DATA = 2'b10, STOP = 2'b11;//***************************************************************************// Reg declarations//*************************************************************************** reg [1:0] state; // Main state machine reg [3:0] over_sample_cnt; // Oversample counter - 16 per bit reg [2:0] bit_cnt; // Bit counter - which bit are we RXing reg char_fifo_pop; // POP indication to FIFO // ANDed with baud_x16_en before module // output//***************************************************************************// Wire declarations//*************************************************************************** wire over_sample_cnt_done; // We are in the middle of a bit wire bit_cnt_done; // This is the last data bit //***************************************************************************// Code//*************************************************************************** // Main state machine always @(posedge clk_tx) begin if (rst_clk_tx) begin state <= IDLE; char_fifo_pop <= 1'b0; end else begin if (baud_x16_en) begin char_fifo_pop <= 1'b0; case (state) IDLE: begin // When the character FIFO is not empty, transition to the START // state if (!char_fifo_empty) begin state <= START; end end // IDLE state START: begin if (over_sample_cnt_done) begin state <= DATA; end // if over_sample_cnt_done end // START state DATA: begin // Once the last bit has been transmitted, send the stop bit // Also, we need to POP the FIFO if (over_sample_cnt_done && bit_cnt_done) begin char_fifo_pop <= 1'b1; state <= STOP; end end // DATA state STOP: begin if (over_sample_cnt_done) begin // If there is no new character to start, return to IDLE, else // start it right away if (char_fifo_empty) begin state <= IDLE; end else begin state <= START; end end end // STOP state endcase end // if baud_x16_en end // if rst_clk_tx end // always // Assert the rd_en to the FIFO for only ONE clock period assign char_fifo_rd_en = char_fifo_pop && baud_x16_en; // Oversample counter // Pre-load whenever we are starting a new character (in IDLE or in STOP), // or whenever we are within a character (when we are in START or DATA). always @(posedge clk_tx) begin if (rst_clk_tx) begin over_sample_cnt <= 4'd0; end else begin if (baud_x16_en) begin if (!over_sample_cnt_done) begin over_sample_cnt <= over_sample_cnt - 1'b1; end else begin if (((state == IDLE) && !char_fifo_empty) || (state == START) || (state == DATA) || ((state == STOP) && !char_fifo_empty)) begin over_sample_cnt <= 4'd15; end end end // if baud_x16_en end // if rst_clk_tx end // always assign over_sample_cnt_done = (over_sample_cnt == 4'd0); // Track which bit we are about to transmit // Set to 0 in the START state // Increment in all DATA states always @(posedge clk_tx) begin if (rst_clk_tx) begin bit_cnt <= 3'b0; end else begin if (baud_x16_en) begin if (over_sample_cnt_done) begin if (state == START) begin bit_cnt <= 3'd0; end else if (state == DATA) begin bit_cnt <= bit_cnt + 1'b1; end end // if over_sample_cnt_done end // if baud_x16_en end // if rst_clk_tx end // always assign bit_cnt_done = (bit_cnt == 3'd7); // Generate the output always @(posedge clk_tx) begin if (rst_clk_tx) begin txd_tx <= 1'b1; end else begin if (baud_x16_en) begin if ((state == STOP) || (state == IDLE)) begin txd_tx <= 1'b1; end else if (state == START) begin txd_tx <= 1'b0; end else // we are in DATA begin txd_tx <= char_fifo_dout[bit_cnt]; end end // if baud_x16_en end // if rst end // alwaysendmodule
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -