📄 m3s001an.v
字号:
// Transmit Engine// Copyright Mentor Graphics Corporation and Licensors 1999// V1.201// This module provides the transmit mechanism// for the M16550a UART.// Revision history:// V1.201 - 9 September 1999// DP asynchronously reset to avoid potential gate-level simulation problem// V1.200 - 16 June 1999// Remove unused variable Stop (ECN 1242)// V1.100 - 30 April 1999// Uses single input clock// V1.000 - 26/9/96// Original// Transmit state machine// 14 states are required:`define C_TX_IDLE 4'h0`define C_TX_START 4'h1`define C_TX_DATA1 4'h2`define C_TX_DATA2 4'h3`define C_TX_DATA3 4'h4`define C_TX_DATA4 4'h5`define C_TX_DATA5 4'h6`define C_TX_DATA6 4'h7`define C_TX_DATA7 4'h8`define C_TX_DATA8 4'h9`define C_TX_PARITY 4'ha`define C_TX_STOP1 4'hb`define C_TX_STOP2 4'hcmodule m3s001an( CLK, MR, TxClkEnab, NWR, ADD0, TFD, DI, PEN, WLS0, WLS1, STB, EPS, SP, FIFOE, TEmpt, TXD, THRe, TSRE, LoadTxBuff );input CLK, MR, TxClkEnab, NWR, ADD0;input [7:0] DI, TFD;input PEN, WLS0, WLS1;input STB, EPS, SP, FIFOE, TEmpt;output TXD, THRe, TSRE, LoadTxBuff;reg [7:0] TD, DO;reg [3:0] StepC, TxState;reg TXMD, TXD, DP, PTY;reg THRe1, THRe2, THRe3, THRe;reg Start, ITHRe, TSRE;reg Step, HStep, NeStep;reg TxEnab;wire LoadTxBuff;// Transmit Hold Registeralways @(posedge NWR) if (ADD0) TD[7:0] <= DI[7:0];// THRe - Transmit status flag// Three stage pipeline// After reset THRe is set - TX Holding register empty//// THRe1 is set by a write to the TX shift register// THRe2 synchronises to the next TX clock edge // THRe2 is shifted into THRe3 at the start of the next TX character// At the next write to the TX shift register THRe1 is toggled because// it feeds back the inverse of THRe3, and the process repeats//// ITHRe is the EXNOR of THRe2 and THRe3// TEmpt is for the Tx fifo// THRe is a multiplexed version of these two signals// Start indicates that the Tx shift register is being loadedalways @(TxClkEnab or Step or TxState or PEN)begin Start = (TxClkEnab & Step & (TxState == `C_TX_START));endassign LoadTxBuff = Start;// Now the THRe handshakealways @(posedge NWR or posedge MR) if (MR) THRe1 <= 1'b0; else if (ADD0) THRe1 <= ~THRe3;always @(posedge CLK or posedge MR) if (MR) THRe2 <= 1'b0; else THRe2 <= THRe1;always @(posedge CLK or posedge MR) if (MR) THRe3 <= 1'b0; else if (TxClkEnab & Step & (TxState == `C_TX_START)) THRe3 <= THRe2;always @(THRe2 or THRe3) ITHRe = ~(THRe2 ^ THRe3);// THRe muxalways @(FIFOE or TEmpt or ITHRe) if (FIFOE) THRe = TEmpt; else THRe = ITHRe;// Enable transmission when data is available// and the transmitter is not disabled by flow controlalways @(THRe) TxEnab = ~THRe;// Transmit Shift Register empty is THRe AND TX Idlealways @(THRe or TxState) TSRE = (THRe & (TxState == `C_TX_IDLE));// Transmit data latch// This latches in the data to be transmitted// At the start bit of the character (ST00)always @(posedge CLK) if (Start & ~FIFOE) DO <= TD; else if (Start & FIFOE) // THR & Tx Fifo data mux DO <= TFD;// Transmit Step timer - divides the baud rate by 16 to generate// the 'Step' or move onto next bit enable signalalways @(posedge CLK or posedge MR) if (MR) StepC[3:0] <= 4'b0000; else if (TxClkEnab & TxState == `C_TX_IDLE) StepC[3:0] <= 4'b0000; else if (TxClkEnab) StepC[3:0] <= (StepC[3:0] + 1);// Step - Count of 15// NeStep - Count of 14// HStep - Count of 6 - When data is outputalways @(StepC)begin Step = (StepC == 4'hF); NeStep = (StepC == 4'hE); HStep = (StepC == 4'h6);end// Transmit state machine// This controls the whole transmit operationalways @(posedge CLK or posedge MR)begin if (MR) TxState <= `C_TX_IDLE; else if (TxClkEnab) begin case (TxState) `C_TX_IDLE: if (TxEnab) TxState <= `C_TX_START; `C_TX_START: if (Step) TxState <= `C_TX_DATA1; `C_TX_DATA1: if (Step) TxState <= `C_TX_DATA2; `C_TX_DATA2: if (Step) TxState <= `C_TX_DATA3; `C_TX_DATA3: if (Step) TxState <= `C_TX_DATA4; `C_TX_DATA4: if (Step) TxState <= `C_TX_DATA5; `C_TX_DATA5: if (Step) TxState <= `C_TX_DATA6; `C_TX_DATA6: if ((~(WLS1 | WLS0)) | Step) TxState <= `C_TX_DATA7; `C_TX_DATA7: if ((~WLS1) | Step) TxState <= `C_TX_DATA8; `C_TX_DATA8: if ((~(WLS1 & WLS0)) | Step) TxState <= `C_TX_PARITY; `C_TX_PARITY: if (~PEN | Step) TxState <= `C_TX_STOP1; `C_TX_STOP1: if (~STB | Step) TxState <= `C_TX_STOP2; `C_TX_STOP2: if (NeStep | (~WLS1 & ~WLS0 & STB & HStep)) TxState <= `C_TX_IDLE; default: TxState <= `C_TX_IDLE; endcase endend// Output data multiplexingalways @(TxState or DO or PTY)begin case (TxState) `C_TX_IDLE: TXMD = 1'b1; // Idle TX value is '1' `C_TX_START: TXMD = 1'b0; // Start bit value is '0' `C_TX_DATA1: TXMD = DO[0]; `C_TX_DATA2: TXMD = DO[1]; `C_TX_DATA3: TXMD = DO[2]; `C_TX_DATA4: TXMD = DO[3]; `C_TX_DATA5: TXMD = DO[4]; `C_TX_DATA6: TXMD = DO[5]; `C_TX_DATA7: TXMD = DO[6]; `C_TX_DATA8: TXMD = DO[7]; `C_TX_PARITY:TXMD = PTY; default: TXMD = 1'b1; // Default and stop bit state is '1' endcaseend// Synchronise the output data stream and remove glitches// Normal output or IR modulated output selectedalways @(posedge CLK or posedge MR) if (MR) TXD <= 1; else if (HStep) TXD <= TXMD;// Generate parity serially, clearing down after every character TXalways @(posedge CLK or posedge MR) if (MR) DP <= 0; else if ((TxState == `C_TX_START) & TxClkEnab) DP <= 0; else if (HStep & TxClkEnab) DP <= (TXMD ^ DP); // EXOR DP and current data bit// Generate parity, if required of the right polarityalways @(EPS or SP or DP) PTY = ~(EPS ^ (~(SP | ~DP)));endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -