⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m3s002an.v

📁 mentor UART IP verilog源码 以通过验证.
💻 V
字号:
// Receive Engine// Copyright Mentor Graphics Corporation and Licensors 2001// V1.400// This module provides the receive mechanism// for the M16550a UART.// Revision history:// V1.400  - 5 Mar 2001//           FIFOE used to avoid a spurious line status interrup (OE)//           when the Recieve FIFO is disabled (ECN01450).// V1.300  - 30 Jan 2001 //           Removed RxClkEnab from Timeout Counter (ECN01437).// V1.200  - 15 June 1999//           Remove unused signals BREAK, CR (ECN 1242)//           Changed constants from 2'b0 to 2'b00 to clear lint warning (ECN 1242)// V1.100  - 12 May 1999//           Uses single input clock// V1.000  - 26/9/96//           Original// Receive state machine// 14 states are required:`define C_RX_IDLE 4'h0`define C_RX_START 4'h1`define C_RX_DATA1 4'h2`define C_RX_DATA2 4'h3`define C_RX_DATA3 4'h4`define C_RX_DATA4 4'h5`define C_RX_DATA5 4'h6`define C_RX_DATA6 4'h7`define C_RX_DATA7 4'h8`define C_RX_DATA8 4'h9`define C_RX_PARITY 4'ha`define C_RX_STOP1 4'hb`define C_RX_CHARX 4'hc`define C_RX_END_BRK 4'hd// Seven bits`define C_RTO 4'b0111module m3s002an (  CLK, MR, RxClkEnab, NRD, PRD, ADD0, ADD5,  DA4, DA3, DA2, DA1,  PEN, WLS0, WLS1, STB, EPS, SP,  SIN, LOOP1, BRKTD, RFD,  FOE, FPE, FFE, FBI, FERF, FIFOE, REmpt, RRST,  RD, RX, CharEn, DR, FE, OE, PE, BI,  ERF, RTO, FRE, PTE, FBRK, RxBlank  );input       CLK, MR, RxClkEnab, NRD, PRD, ADD0, ADD5;input       DA4, DA3, DA2, DA1;input       PEN, WLS0, WLS1, STB, EPS, SP;input       SIN, LOOP1, BRKTD;input [7:0] RFD;input       FOE, FPE, FFE, FBI, FERF;input       FIFOE, REmpt, RRST;output [7:0] RD, RX;output       CharEn;output       DR, FE, OE, PE, BI;output       ERF;     // At least one error in fifooutput       RTO;     // Rx character timeoutoutput       FRE, PTE, FBRK, RxBlank;reg [7:0] RX, RXD, RD;reg [3:0] StepC, RxState;reg [2:0] RXS;reg [1:0] OESR, PESR, BRKSR, FESR, DRSR, RDSR;reg [5:0] TOC;reg       DIN, PTY, FRE, DRD;reg       DP, DOE, DBI, DFE, DPE;reg       DR, FE, OE, PE, BI, ERF;reg       SDIN, RDS, RTO;reg       IDLE, RxBlank;reg       Step, SRD;reg       BRK, FBRK, PTE, CharEn;reg       IDR, IFE, IOE, IPE, IBI;reg       NoBit6, NoBit7, NoBit8;reg       IpFilter;// Input data is either SIN or TX data looped backalways @(LOOP1 or SIN or BRKTD)  SDIN = (~LOOP1 & SIN) | (LOOP1 & ~BRKTD);// Input data filter, filters incoming data using a majority// 2 of 3 logic circuit - also resyncs data to RX Clockalways @(posedge CLK or posedge MR)  if (MR)    RXS[2:0] <= 3'b111;  else if (RxClkEnab)  begin    RXS[0] <= SDIN;    RXS[1] <= RXS[0];    RXS[2] <= RXS[1];  endalways @(RXS)  IpFilter = (RXS[0] & RXS[1]) | (RXS[0] & RXS[2]) | (RXS[1] & RXS[2]);// Input data selected from input filteralways @(posedge CLK or posedge MR)  if (MR)    DIN <= 1;  else if (RxClkEnab)    DIN <= IpFilter;// Receive 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 <= 0;  else begin    if ((RxState == `C_RX_IDLE) & RxClkEnab & ~DIN)      StepC <=0;    else if (RxClkEnab)      StepC <= StepC + 1;  end// Step - Count of 7always @(RxClkEnab or StepC)  Step = ((StepC == 4'h7) & RxClkEnab);// Decode number of bits required for the characteralways @(WLS0 or WLS1)begin  NoBit6 = ~WLS1 & ~WLS0;  NoBit7 = ~WLS1;  NoBit8 = ~WLS1 | ~WLS0;end// Receive state machine// This controls the whole Receive operationalways @(posedge CLK or posedge MR)begin  if (MR)      RxState <= `C_RX_IDLE;  else if (RxClkEnab)  begin      case (RxState)        `C_RX_IDLE:  if (~DIN)          RxState <= `C_RX_START;  // Detect start bit        `C_RX_START: if (Step & ~DIN)   RxState <= `C_RX_DATA1;                     else if (Step)     RxState <= `C_RX_IDLE;   // If false start stop RX        `C_RX_DATA1: if (Step)          RxState <= `C_RX_DATA2;        `C_RX_DATA2: if (Step)          RxState <= `C_RX_DATA3;        `C_RX_DATA3: if (Step)          RxState <= `C_RX_DATA4;        `C_RX_DATA4: if (Step)          RxState <= `C_RX_DATA5;        `C_RX_DATA5: if (Step)          RxState <= `C_RX_DATA6;        `C_RX_DATA6: if (NoBit6 | Step) RxState <= `C_RX_DATA7;        `C_RX_DATA7: if (NoBit7 | Step) RxState <= `C_RX_DATA8;        `C_RX_DATA8: if (NoBit8 | Step) RxState <= `C_RX_PARITY;        `C_RX_PARITY: if (~PEN | Step)  RxState <= `C_RX_STOP1;        `C_RX_STOP1: if (Step)          RxState <= `C_RX_CHARX;        `C_RX_CHARX:   RxState <= `C_RX_END_BRK;        `C_RX_END_BRK: if (DIN)  RxState <= `C_RX_IDLE;         	       else if (~DIN & BRK) RxState <= `C_RX_START;         default:  RxState <= `C_RX_IDLE;      endcase    endend// IDLE is true is BREAK or IDLE condition is metalways @(posedge CLK or posedge MR)  if (MR) IDLE <= 1'b0;  else if (~FIFOE) IDLE <= 1'b0;  else IDLE <= (((RxState == `C_RX_END_BRK) & RxClkEnab) | (IDLE & DIN));// CPU channel read pulse synchronisationalways @(posedge PRD or posedge MR)  if (MR)    RDS <= 1'b0;  else if (ADD0)    RDS <= ~RDSR[1];always @(posedge CLK or posedge MR)  if (MR)    RDSR[1:0] <= 2'b00;  else if (RxClkEnab)  begin     RDSR[0] <= RDS;    RDSR[1] <= RDSR[0];   end// Synchronised RBR read signalalways @(RDS or RDSR)  SRD = RDS ^ RDSR[1];// Timeout counter//// NOTE. IDLE becomes active at end of received CHARACTER, and inactive// at start of next CHARalways @(posedge CLK or posedge MR)  if (MR)    TOC <= 0;  else if ((~IDLE & ~RTO)  | SRD | RRST)     // Other reset conditions    TOC <= 0;  else if (IDLE & ~REmpt & Step & ~RTO)      // Waiting and something in fifo    TOC <= TOC + 1;// Timeout error flag// indicates 4 character periods have passed//// Default value of 7 = Start bit, 5-data bits and 1 Stop bitalways @(TOC or WLS0 or WLS1 or PEN or STB)  RTO = (TOC[5:0] == {(`C_RTO + ({WLS1,WLS0}) + PEN + STB),2'b00});// Receive buffer data multiplexingalways @(posedge CLK)begin  case (RxState)    `C_RX_IDLE: begin	          RX[7:0] <= 8'b00000000;	          PTY <= 1'b0;	          FRE <= 1'b0;	        end   `C_RX_DATA1: if (Step) RX[0] <= DIN;   `C_RX_DATA2: if (Step) RX[1] <= DIN;   `C_RX_DATA3: if (Step) RX[2] <= DIN;   `C_RX_DATA4: if (Step) RX[3] <= DIN;   `C_RX_DATA5: if (Step) RX[4] <= DIN;   `C_RX_DATA6: if (Step) RX[5] <= DIN;   `C_RX_DATA7: if (Step) RX[6] <= DIN;   `C_RX_DATA8: if (Step) RX[7] <= DIN;   `C_RX_PARITY: if (Step) PTY <= DIN;   `C_RX_STOP1: if (Step) FRE <= ~DIN; // Framing error if DIN not 1 at Framing bit   default: begin	      RX <= RX;	      PTY <= PTY;	      FRE <= FRE;	    end  endcaseend// Check parity serially, clearing down after every character RXalways @(posedge CLK or posedge MR)  if (MR)    DP <= 0;  else if (RxState == `C_RX_START)     DP <= 0;  else if (Step & (RxState != `C_RX_PARITY) & (RxState != `C_RX_STOP1))    DP <= (DIN ^ DP);// Generate parity error, if one has occured:always @(PEN or EPS or PTY or SP or DP)  PTE = ~(~PEN | ((EPS ^ PTY) ^ (~(SP | ~DP))));// Monitor for break condition// If RX shift register detectes all 0's for a whole character// period - by being full of 0's then we have a break character// and generate a BI immediately// Break detection reset on return to IDLE statealways @(RX or FRE or PTY)  BRK = (RX[7] | RX[6] | RX[5] | RX[4] | RX[3] | RX[2] | RX[1] | RX[0] | ~FRE | PTY);always @(BRK)  FBRK = ~BRK;// Generate a signal which says that we are in Character RX state// and BEN is active// Also need to blank LSR Read-back info during CharEn period if not// in FIFO modealways @(RxClkEnab or RxState)  CharEn = ((RxState == `C_RX_CHARX) & RxClkEnab);always @(negedge CLK)  RxBlank <= (CharEn & ~FIFOE);// RXD Data Holding registeralways @(posedge CLK or posedge MR)  if (MR)    RXD[7:0] <= 8'b0000000;  else if (CharEn)    RXD[7:0] <= RX[7:0];// Now for the error and status bits// Start with the Data Ready bit - DRalways @(posedge PRD or posedge MR)  if (MR)    DRD <= 1'b0; else if (ADD0)    DRD <= DRSR[1];always @(posedge CLK or posedge MR)  if (MR)    DRSR[1:0] <= 2'b00;  else if (CharEn)  begin    DRSR[0] <= ~DRD;    DRSR[1] <= DRSR[0];  end  else if (RxClkEnab)  begin    DRSR[1] <= DRSR[0];    DRSR[0] <= DRSR[0];  endalways @(DRD or DRSR)  IDR = DRD ^ DRSR[1];// Overrun Error Bitalways @(posedge CLK or posedge MR)  if (MR)    OESR[1:0] <= 2'b00;  else if (CharEn) // if we have new data in the RX shift register    if (DR & (FIFOE==0)) // if the RX register is full and the FIFO is disabled    // at this point we must use the logic FIFOE==0 since this portion of logic    // sets the OE bit whenever the FIFO is disabled     // there is a separate logic to detect the OE whenever the FIFO is enabled    // this logic can be found in module 8    begin // then set the Overun error bit      OESR[0] <= ~DOE;     // set the overrun error      OESR[1] <= OESR[0];  // set the overrun error	    end    else    begin      OESR[1] <= OESR[0];      OESR[0] <= OESR[0];    end  else if (RxClkEnab)  begin    OESR[1] <= OESR[0];    OESR[0] <= OESR[0];  endalways @(posedge NRD or posedge MR)  if (MR)    DOE <= 1'b0;   else if (DA1 & ADD5)    DOE <= OESR[1];always @(DOE or OESR)  IOE = DOE ^ OESR[1];// Parity Error Bitalways @(posedge CLK or posedge MR)  if (MR)    PESR[1:0] <= 2'b00;  else if (CharEn)    if (PTE)    begin      PESR[0] <= ~DPE;      PESR[1] <= PESR[0];	    end    else if (PE)    begin      PESR[1] <= ~PESR[0];      PESR[0] <= ~PESR[0];    end    else    begin      PESR[1] <= PESR[0];      PESR[0] <= PESR[0];    end  else if (RxClkEnab)  begin    PESR[1] <= PESR[0];    PESR[0] <= PESR[0];  endalways @(posedge NRD or posedge MR)  if (MR)    DPE <= 1'b0;  else if (DA2 & ADD5)    DPE <= PESR[1];always @(DPE or PESR)  IPE = DPE ^ PESR[1];//  Break Indication Bitalways @(posedge CLK or posedge MR)  if (MR)    BRKSR[1:0] <= 2'b00;  else if (CharEn & !BRK)  begin    BRKSR[0] <= ~DBI;    BRKSR[1] <= BRKSR[0];	  end  else if (RxClkEnab)  begin    BRKSR[1] <= BRKSR[0];    BRKSR[0] <= BRKSR[0];  endalways @(posedge NRD or posedge MR)  if (MR)    DBI <= 1'b0;  else if (DA4 & ADD5)    DBI <= BRKSR[1];always @(DBI or BRKSR)  IBI = DBI ^ BRKSR[1];// Framing Error Bitalways @(posedge CLK or posedge MR)  if (MR)    FESR[1:0] <= 2'b00;  else if (CharEn)    if (FRE)    begin      FESR[0] <= ~DFE;      FESR[1] <= FESR[0];	    end    else if (FE)    begin      FESR[1] <= ~FESR[0];      FESR[0] <= ~FESR[0];    end    else    begin      FESR[1] <= FESR[0];      FESR[0] <= FESR[0];    end  else if (RxClkEnab)  begin    FESR[1] <= FESR[0];    FESR[0] <= FESR[0];  endalways @(posedge NRD or posedge MR)  if (MR)    DFE <= 1'b0;  else if (DA3 & ADD5)    DFE <= FESR[1];always @(DFE or FESR)  IFE = DFE ^ FESR[1];// Data mux to select between RBR and Rx Fifo// Including error flagsalways @(RFD or RXD or REmpt or IDR or FOE or IOE or FPE         or IPE or FFE or IFE or FBI or IBI or FERF or FIFOE)  if (FIFOE)  begin    RD[7:0] = RFD[7:0];    DR      = ~REmpt;    OE      = FOE;    PE      = FPE;    FE      = FFE;    BI      = FBI;    ERF     = FERF;  end  else  begin    RD[7:0] = RXD[7:0];    DR      = IDR;    OE      = IOE;    PE      = IPE;    FE      = IFE;    BI      = IBI;    ERF     = 1'b0;  endendmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -