URL
https://opencores.org/ocsvn/ssp_uart/ssp_uart/trunk
Subversion Repositories ssp_uart
Compare Revisions
- This comparison shows the changes necessary to convert path
/ssp_uart
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/RTL/re1ce.v
0,0 → 1,111
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2006-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: Alpha Beta Technologies, Inc. |
// Engineer: Michael A. Morris |
// |
// Create Date: 11:45:29 12/31/2006 |
// Design Name: USB MBP HDL |
// Module Name: re1ce |
// Project Name: USBMBP_HDL |
// Target Devices: XC2S15-5TQ144 |
// Tool versions: ISE Webpack 8.2i |
// Description: Multi-stage synchronizer with rising edge detection |
// |
// Dependencies: None |
// |
// Revision History: |
// |
// 0.01 06L31 MAM File Created |
// |
// 1.00 13G06 MAM Added initial values for the sync FFs |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module re1ce(den, din, clk, rst, trg, pls); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Port Declarations |
// |
|
input den; |
input din; |
input clk; |
input rst; |
output trg; |
output pls; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Level Declarations |
// |
|
reg QIn; |
reg [2:0] QSync; |
|
wire Rst_QIn; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
assign Rst_QIn = (rst | pls); |
|
always @(posedge din or posedge Rst_QIn) begin |
if(Rst_QIn) |
#1 QIn <= 1'b0; |
else if(den) |
#1 QIn <= den; |
end |
assign trg = QIn; |
|
always @(posedge clk or posedge rst) begin |
if(rst) |
#1 QSync <= 3'b0; |
else |
#1 QSync <= {QSync[0] & ~QSync[1], QSync[0], QIn}; |
end |
assign pls = QSync[2]; |
|
endmodule |
/trunk/RTL/UART_RTO.v
0,0 → 1,239
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 06:50:40 06/14/2008 |
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/UART_RTO.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This module implements a receive timeout timer which sets a |
// flag to indicate that the timeout occured. The flag is cleared |
// by reset or by the reading of the Receive Holding Register. |
// |
// The Receive Timeout Val should be set by the client module to a |
// value which corresponds to the desired timeout value in terms |
// of the number of bit times. This module scales the 16x bit rate |
// clock enable by 16 to set the internal bit rate clock enable. |
// The client module provide the character frame length and the |
// number of characters to delay. The character frame length |
// varies as a function of the frame format, e.g. 8N1, 8E2, or |
// 7O1. The number of characters to delay for the timeout is a |
// fixed number of character periods, e.g. 3, in most cases. The |
// module allows these values to be independently specified. |
// |
// |
// Dependencies: none |
// |
// Revision History: |
// |
// 0.01 08E14 MAM File Created |
// |
// 1.00 08E14 MAM Initial Release |
// |
// 1.10 08E14 MAM Changed the input parameters to have two delay |
// parameters: CCntVal - character length; and |
// RTOVal - # characters to delay. |
// The result is a faster implementation, and one |
// the RTOVal can usually be set as a constant. |
// |
// 1.11 08E15 MAM Changed Module Name |
// |
// 2.00 11B06 MAM Converted to Verilog 2001. |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module UART_RTO( |
input Rst, |
input Clk, |
|
input CE_16x, |
|
input WE_RHR, |
input RE_RHR, |
|
input [3:0] CCntVal, |
input [3:0] RTOVal, |
|
output reg RcvTimeout |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Local Signal Declarations |
// |
|
wire Clr_RTOArm; |
reg RTOArm; |
|
wire Clr_BCnt; |
reg [3:0] BCnt; |
reg TC_BCnt; |
|
wire Clr_CCnt; |
reg [3:0] CCnt; |
reg TC_CCnt; |
|
wire Clr_RTOCnt, CE_RTOCnt; |
reg [3:0] RTOCnt; |
reg TC_RTOCnt; |
|
wire Clr_RTO, CE_RTO; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
// RTO Arm FF |
// Armed with each received character, cleared by Rst, RE_RHR, or timeout |
// |
|
assign Clr_RTOArm = RE_RHR | CE_RTO; |
|
always @(posedge Clk) |
begin |
if(Rst) |
RTOArm <= #1 0; |
else if(Clr_RTOArm) |
RTOArm <= #1 0; |
else if(WE_RHR) |
RTOArm <= #1 1; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Bit Rate Divider |
// Held in reset until RTO Armed or if Rst asserted |
// |
|
assign Clr_BCnt = Rst | WE_RHR | Clr_RTOArm | ~RTOArm; |
|
always @(posedge Clk) |
begin |
if(Clr_BCnt) |
BCnt <= #1 0; |
else if(CE_16x) |
BCnt <= #1 BCnt + 1; |
end |
|
always @(posedge Clk) |
begin |
if(Clr_BCnt) |
TC_BCnt <= #1 0; |
else if(CE_16x) |
TC_BCnt <= #1 (BCnt == 4'b1110); |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Character Frame Divider |
// Held in reset until RTO Armed or if Rst asserted |
// |
|
assign Clr_CCnt = Clr_BCnt; |
assign CE_CCnt = CE_16x & TC_BCnt; |
|
always @(posedge Clk) |
begin |
if(Clr_CCnt) |
CCnt <= #1 CCntVal; |
else if(CE_CCnt) |
CCnt <= #1 ((TC_CCnt) ? CCntVal : CCnt - 1); |
end |
|
always @(posedge Clk) |
begin |
if(Clr_CCnt) |
TC_CCnt <= #1 0; |
else if(CE_16x) |
TC_CCnt <= #1 (CCnt == 0); |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Receive Timeout Counter |
// Held in reset until RTO Armed or if Rst asserted |
// Counts bit periods when RTO Armed |
|
assign Clr_RTOCnt = Clr_BCnt; |
assign CE_RTOCnt = CE_16x & TC_BCnt & TC_CCnt; |
|
always @(posedge Clk) |
begin |
if(Clr_RTOCnt) |
RTOCnt <= #1 RTOVal; |
else if(CE_RTOCnt) |
RTOCnt <= #1 ((TC_RTOCnt) ? RTOVal : RTOCnt - 1); |
end |
|
always @(posedge Clk) |
begin |
if(Clr_RTOCnt) |
TC_RTOCnt <= #1 0; |
else if(CE_16x) |
TC_RTOCnt <= #1 (RTOCnt == 0); |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Receive Timeout Latch |
// Cleared by Rst or any read of the RHR |
// Set by RTOCnt terminal count |
|
assign Clr_RTO = RE_RHR; |
assign CE_RTO = CE_16x & TC_BCnt & TC_CCnt & TC_RTOCnt; |
|
always @(posedge Clk) |
begin |
if(Rst) |
RcvTimeout <= #1 0; |
else if(Clr_RTO) |
RcvTimeout <= #1 0; |
else if(CE_RTO) |
RcvTimeout <= #1 1; |
end |
|
endmodule |
/trunk/RTL/DPSFnmCE.v
0,0 → 1,216
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2007-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
//////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 12:11:30 12/22/2007 |
// Design Name: HAWK Interface FPGA, 4020-0420, U35 |
// Module Name: DPSFnmCE |
// Project Name: 4020 HAWK ZAOM Upgrade |
// Target Devices: XC2S150-5PQ208I |
// Tool versions: ISE 8.2i |
// |
// Description: This module implements a parameterized version of a distributed |
// RAM synchronous FIFO. The address width, FIFO width and depth |
// are all specified by parameters. Default parameters settings |
// describe a 16x16 FIFO with Full (FF), Empty (EF), and Half |
// Full (HF) flags. The module also outputs the count words in the |
// FIFO. |
// |
// Dependencies: None |
// |
// Revision History: |
// |
// 0.01 07L22 MAM File Created |
// |
// 0.10 08K05 MAM Changed depth to a localparam based on addr |
// |
// 1.00 13G14 MAM Converted to Verilog 2001 standard |
// |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module DPSFnmCE #( |
parameter addr = 4, // Sets depth of the FIFO: 2**addr |
parameter width = 16, // Sets width of the FIFO |
parameter init = "DPSFnmRAM.coe" // Initializes FIFO memory |
)( |
input Rst, |
input Clk, |
input WE, |
input RE, |
input [(width - 1):0] DI, |
output [(width - 1):0] DO, |
output FF, |
output EF, |
output HF, |
output [addr:0] Cnt |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Module Parameter List |
// |
|
localparam depth = (2**addr); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Module Level Declarations |
// |
|
reg [(width - 1):0] RAM [(depth - 1):0]; |
|
reg [ (addr - 1):0] A, DPRA; |
reg [ (addr - 1):0] WCnt; |
reg nEF, rFF; |
|
wire Wr, Rd, CE; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
// |
// Combinatorial Control Signals |
// |
|
assign Wr = WE & ~FF; |
assign Rd = RE & ~EF; |
assign CE = Wr ^ Rd; |
|
// |
// Write Address Counter |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
A <= #1 0; |
else if(Wr) |
A <= #1 A + 1; |
end |
|
// |
// Read Address Counter |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
DPRA <= #1 0; |
else if(Rd) |
DPRA <= #1 DPRA + 1; |
end |
|
// |
// Word Counter |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
WCnt <= #1 0; |
else if(Wr & ~Rd) |
WCnt <= #1 WCnt + 1; |
else if(Rd & ~Wr) |
WCnt <= #1 WCnt - 1; |
end |
|
// |
// External Word Count |
// |
|
assign Cnt = {FF, WCnt}; |
|
// |
// Empty Flag Register (Active Low) |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
nEF <= #1 0; |
else if(CE) |
nEF <= #1 ~(RE & (Cnt == 1)); |
end |
|
assign EF = ~nEF; |
|
// |
// Full Flag Register |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
rFF <= #1 0; |
else if(CE) |
rFF <= #1 (WE & (&WCnt)); |
end |
|
assign FF = rFF; |
|
// |
// Half-Full Flag |
// |
|
assign HF = Cnt[addr] | Cnt[(addr - 1)]; |
|
// |
// Dual-Port Synchronous RAM |
// |
|
initial |
$readmemh(init, RAM, 0, (depth - 1)); |
|
always @(posedge Clk) |
begin |
if(Wr) |
RAM[A] <= #1 DI; // Synchronous Write |
end |
|
assign DO = RAM[DPRA]; // Asynchronous Read |
|
endmodule |
|
/trunk/RTL/SSP_UART.v
0,0 → 1,1094
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
//////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 12:30:30 05/11/2008 |
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/SSP_UART.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This module integrates the various elements of a simplified |
// UART to create a UART that is efficiently supported using a |
// serial interface. The module also incorporates the logic to |
// support four operating modes, and controls the signal muxes |
// necessary. |
// |
// Dependencies: re1ce.v, BRSFmnCE.v, UART_BRG.v, UART_TXSM.v, UART_RXSM.v, |
// UART_RTO.v, UART_INT.v, redet.v |
// |
// Revision History: |
// |
// 0.01 08E10 MAM File Created |
// |
// 0.10 O8E12 MAM Incorporated the ROMs for decoding the format |
// and buad rate. Updated the interfaces to the |
// BRG, TxSM, and RxSM. |
// |
// 0.11 08E14 MAM Added the RTO ROM for setting the length of the |
// receive timeout interval on the basis of the |
// character frame format. Modified the baud rate |
// table to remove the 300 and 600 baud entries and |
// add entries for 28.8k and 14.4k baud. Reduced the |
// width of the baud rate divider from 10 to 8 bits. |
// |
// 1.00 08G23 MAM Modified the SSP Interface to operate with the new |
// SSPx_Slv interface which uses registers for SSP_DI |
// and SSP_DO. The falling edge of SCK is used for the |
// latching and transfering read/write operations from |
// the SCK clock domain to the Clk clock domain. |
// |
// 1.01 08G24 MAM Corrected error in the TFC/RFC pulse enables that |
// allowed any write to the SSP UART with 1's in these |
// bit positions to generate a THR/RHR FIFO reset. |
// |
// 1.10 08G26 MAM Modified to implement a multiplexed register set |
// with the SPR address. Additional status registers |
// added for various purposes including revision, |
// FIFO output, FIFO len, and FIFO count registers. |
// Since an XC2S30 is required, and there is no other |
// function required in the FPGA, increased the FIFO |
// depth of the Tx FIFO to 128 words using distributed |
// RAM. |
// |
// 1.11 08G27 MAM Modified the organization of the SPR window status |
// registers to match Table 5 in the 17000-0403C SSP |
// UART specification. |
// |
// 1.20 08G27 MAM Modified Tx signal path to include a FF that will |
// prevent the Tx SM from shifting until the Tx FIFO |
// is loaded with the full message up to the size of |
// FIFO. The bit is normally written as a 0 and ORed |
// with the TF_EF. In this state, Tx SM starts the |
// shift operation immediately. When the bit is set, |
// then the OR with the TF_EF prevents the Tx SM from |
// sending the Tx FIFO contents until HLD bit is reset |
// |
// 1.30 08H02 MAM Modified the FIFOs to use the Block RAM FIFOs. |
// Updated the default parameters to set the depth to |
// match the 1024 word depth of the Block RAM FIFOs. |
// |
// 1.40 08H09 MAM Added Rx/Tx FIFO Threshold Resgister, reordered SPR |
// sub-registers to incorporate programmable threshold |
// for the FIFOs into the design. Set the default of |
// the threshold for the Rx/Tx FIFOs to half. |
// |
// 1.41 08H12 MAM Registered the RxD input signal; reset State forced |
// mark condition. Modified the RTFThr register so |
// a logic 1 is required in SSP_DI[8] to write it. |
// |
// 2.00 11B06 MAM Converted to Verilog 2001. Added an external enable |
// signal, reordered the registers, and set the SPI |
// interface to operate in the same manner as for the |
// LTAS module. |
// |
// 2.01 11B08 MAM Changed En to SSP_SSEL, and changed the SSP_DO bus |
// to a tri-state bus enabled by SSP_SSEL so that the |
// module can used along with other SSP-compatible |
// modules in the same FPGA. Corrected minor encoding |
// error for RS/TS fields. |
// |
// 2.10 13G10 MAM Adjusted baud rate table to support Profibus rates |
// from 3M down to 187.5k, and standard baud rates from |
// 1200 to 230.4k baud. |
// |
// 2.20 13G12 MAM Removed baud rate table controlled by 4 bits in the |
// UART control register. Replaced by a 12-bit write- |
// only register mapped to the address of the read-only |
// UART status register. The new Baud Rate Register re- |
// places the the baud rate ROM: PS[3:0] <= BRR[11:8], |
// and Div[7:0] <= BRR[7:8]. (N-1) must be loaded into |
// each of these fields to set the correct divider. |
// Also added parameters for default values for the |
// baud rate generator PS (Prescaler) and Div (Divider) |
// values. Default values selected for 9600 bps at the |
// UART operating frequency, which is 73.728 MHz for |
// this application. |
// |
// 2.30 13G14 MAM Changed the parameterization so module can be para- |
// meterized from the instantiating module. Removed |
// (commented out) Block RAM FIFO instantiations and |
// associated FIFO configuration parameters. Updated |
// the Additional Comments section. |
// |
// 2.40 13G21 MAM Added asynchronous reset to several functions in |
// order to correctly simulate in ISim. |
// |
// 2.50 13G28 MAM Corrected issue with polling of the Receive Data |
// Register. A race condition was found. Corrected by |
// registering the data on the SCK clock domain and |
// by requiring that the read pulse for the receive |
// FIFO is only generated if the empty flag status is |
// present on the SCK clock domain. This prevents the |
// same race condition as found when polling the UART |
// Status Register. Examining the condition/flags of |
// these registers, without polling via the SSP inter- |
// face, avoids these issues. Given the limited I/O |
// resources of the M16C5x, examining the condition/ |
// flags bits directly without polling is not a viable |
// option. Therefore, corrected the race condition. If |
// examining the condition/flags directly is an option, |
// then that is the preferred method from a performance |
// perspective. |
// |
// Additional Comments: |
// |
// The SSP UART is defined in 1700-0403C. The following is a summary of the |
// register and field definitions contained in the referenced document. If any |
// conflicts arise in the definitions, the implementation defined in this file |
// will take precedence over the document. |
// |
// The UART consists of six registers: |
// |
// (1) UCR - UART Control Register (3'b000) |
// (2) USR - UART Status Register (3'b001) |
// (3) BRR - Baud Rate Register (3'b001) |
// (3) TDR - Transmit Data Register (3'b010) |
// (4) RDR - Receive Data Register (3'b011) |
// (5) SPR - Scratch Pad Register (3'b100) |
// |
// The Synchronous Serial Peripheral of the ARM is configured to send 16 bits. |
// The result is that the 3 most significant bits are interpreted as an regis- |
// ter select. Bit 12, the fourth transmitted bit, set the write/read mode of |
// transfer. The remaining twelve bits, bits 11...0, are data bits. In this |
// manner, the SSP UART minimizes the number of serial transfers required to |
// send and receive serial data from the SSP UART. The reads from the TDR/RDR |
// addresses also provide status information regarding the transmit and receive |
// state machines, and the FIFO-based holding registers. Thus, polling of the |
// status register is not necessary in most circumstances to determine if the |
// FIFOs are ready to receive data from the host or have data to provide the |
// host. |
// |
// With each SSP/SPI operation to the TDR/RDR address, the SSP UART will read |
// and write the receive and transmit holding registers, respectively. These |
// holding registers are implemented using 9-bit and 8-bit FIFOs, respective- |
// ly. The FIFOs are independently configured so that they can be easily |
// replaced with other implementations as required. |
// |
// The USR implements a read-only register for the UART status bits other than |
// the RERR - Receiver Error, RTO - Receiver Time-Out, RRDY - Receiver Ready, |
// and the TRDY - Transmitter Ready status bits read out in the RDR. The USR |
// provides access to the UART mode and baud rate bits from the UCR. The RTSi |
// and CTSi bits reflect the state of the external RTS and CTS signals in the |
// RS-232 modes. In the RS-485 modes, RTSi reflects the state of the external |
// transceiver drive enable signal, and CTSi should be read as a logic 1. The |
// CTSi bit is set internally to a logic 1 by the SSP UART in the RS-485 modes |
// because it is always ready to receive. The receiver serial input data pin |
// is controlled in the RS-485 modes so that the external transceiver output |
// enable can always be enabled. |
// |
// UART Control Register - UCR (RA = 3'b000) |
// |
// 11:10 - MD : Mode (see table below) |
// 9 - RTSo: Request To Send, set to assert external RTS in Mode 0 |
// 8 - IE : Interrupt Enable, set to enable Xmt/Rcv interrupts |
// 7:4 - FMT : Format (see table below) |
// 3:0 - Rsvd: Reserved (previously used for Baud Rate (see table below)) |
// |
// UART Status Register - USR (RA = 3'b001) (Read-Only) |
// |
// 11:10 - MD : Mode (see table below) |
// 9 - RTSi: Request To Send In, set as discussed above |
// 8 - CTSi: Clear To Send In, set as discussed above |
// 7:6 - RS : Receive Status: 0 - Empty, 1 < Half, 2 >= Half, 3 - Full |
// 5:4 - TS : Transmit Status: 0 - Empty, 1 < Half, 2 >= Half, 3 - Full |
// 3 - iRTO: Receive Timeout Interrupt Flag |
// 2 - iRDA: Receive Data Available Interupt Flag (FIFO >= Half Full) |
// 1 - iTHE: Transmit FIFO Half Empty Interrupt Flag |
// 0 - iTFE: Transmit FIFO Empty Interrupt Flag |
// |
// Buad Rate Register - BRR (RA = 3'b001) (Write-Only) |
// |
// 11:8 - PS : Baud Rate Prescaler (see table below) - load with (M - 1) |
// 7:0 - Div : Baud Rate Divider (see table below) - load with (N - 1) |
// |
// {PS, Div} : Baud Rate = (Clk / 16) / ((M - 1) * (N - 1)) |
// |
// Transmit Data Register - TDR (RA = 3'b010) |
// |
// 11 - TFC : Transmit FIFO Clear, cleared at end of current cycle |
// 10 - RFC : Receive FIFO Clear, cleared at end of current cycle |
// 9 - HLD : Transmit Hold: 0 - normal; 1 - hold until Tx FIFO filled |
// 8 - Rsvd : Reserved for Future Use |
// 7:0 - TD : Transmit Data, written to Xmit FIFO when WnR is set. |
// |
// Receive Data Register - RDR (RA = 3'b011) |
// |
// 11 - TRDY : Transmit Ready, set if Xmt FIFO not full |
// 10 - RRDY : Receive Ready, set if Rcv FIFO has data |
// 9 - RTO : Receive Time Out, set if no data received in 3 char. times |
// 8 - RERR : Receiver Error, set if current RD[7:0] has an error |
// 7:0 - RD : Receive Data |
// |
// Scratch Pad Register - SPR (RA = 3'b100) |
// |
// 11:0 - SPR : Scratch Pad Data, R/W location set by bits 11:9 (see below) |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// MD[1:0] - Operating Mode |
// |
// 2'b00 - RS-232 without Handshaking, xRTS <= RTSi <= RTSo, CTSi <= xCTS |
// 2'b01 - RS-232 with Handshaking, xRTS <= RTSi <= ~TxIdle, CTSi <= xCTS |
// 2'b10 - RS-485 without Loopback, RD <= CTSi <= 1, DE <= RTSi <= ~TxIdle |
// 2'b11 - RS-485 with Loopback, RD <= RxD, DE <= RTSi <= ~TxIdle, CTSi <= 1 |
// |
// FMT[3:0] - Asynchronous Serial Format |
// |
// 4'b0000 - 8N1, 4'b1000 - 8O2 |
// 4'b0001 - 8N1, 4'b1001 - 8E2 |
// 4'b0010 - 8O1, 4'b1010 - 8S2 |
// 4'b0011 - 8E1, 4'b1011 - 8M2 |
// 4'b0100 - 8S1, 4'b1100 - 7O1 |
// 4'b0101 - 8M1, 4'b1101 - 7E1 |
// 4'b0110 - 8N1, 4'b1110 - 7O2 |
// 4'b0111 - 8N2, 4'b1111 - 7E2 |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// SPR Sub-Addresses - Additional Status Registers |
// |
// Accessed by setting SPR[11:9] to the address of the desired extended |
// status register. Unused bits in the status registers set to 0. |
// Unassigned sub-addresses default to the SPR. |
// |
// 1 - [7:0] Revision Register |
// 2 - [7:0] FIFO Length: RFLen - 7:4, TFLen - 3:0; (1 << (xFLen + 4)) |
// 3 - [7:0] Rx/Tx FIFO Threshold: RFThr - 7:4, TFThr - 3:0; (xFLen >> 1) |
// 4 - [7:0] Tx Holding Register, "peeking" into THR does not advance Tx FIFO |
// 5 - [8:0] Rx Holding Register, "peeking" into RHR does not advance Rx FIFO |
// 6 - [(TFLen + 4):0] Tx FIFO Count |
// 7 - [(RFLen + 4):0] Rx FIFO Count |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module SSP_UART #( |
// Default BRR Settings Parameters |
|
parameter pPS_Default = 4'h1, // see baud rate tables below |
parameter pDiv_Default = 8'hEF, // see baud rate tables below |
|
// Default Receive Time Out Character Delay Count |
|
parameter pRTOChrDlyCnt = 3, |
|
// FIFO Configuration Parameters |
|
parameter pTF_Depth = 0, // Tx FIFO Depth: 2**(TF_Depth + 4) |
parameter pRF_Depth = 3, // Rx FIFO Depth: 2**(RF_Depth + 4) |
parameter pTF_Init = "Src/UART_TF.coe", // Tx FIFO Memory Initialization |
parameter pRF_Init = "Src/UART_RF.coe" // Rx FIFO Memory Initialization |
)( |
input Rst, // System Reset |
input Clk, // System Clock |
|
// SSP Interface |
|
input SSP_SSEL, // SSP Slave Select |
|
input SSP_SCK, // Synchronous Serial Port Serial Clock |
input [2:0] SSP_RA, // SSP Register Address |
input SSP_WnR, // SSP Command |
input SSP_En, // SSP Start Data Transfer Phase (Bits 11:0) |
input SSP_EOC, // SSP End-Of-Cycle (Bit 0) |
input [11:0] SSP_DI, // SSP Data In |
output reg [11:0] SSP_DO, // SSP Data Out |
|
// External UART Interface |
|
output TxD_232, // RS-232 Mode TxD |
input RxD_232, // RS-232 Mode RxD |
output reg xRTS, // RS-232 Mode RTS (Ready-To-Receive) |
input xCTS, // RS-232 Mode CTS (Okay-To-Send) |
|
output TxD_485, // RS-485 Mode TxD |
input RxD_485, // RS-485 Mode RxD |
output xDE, // RS-485 Mode Transceiver Drive Enable |
|
// External Interrupt Request |
|
output reg IRQ, // Interrupt Request |
|
// TxSM/RxSM Status |
|
output TxIdle, |
output RxIdle |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Module Parameters |
// |
|
localparam pVersion = 8'h23; // Version: 2.3 |
|
// Register Addresses |
|
localparam pUCR = 0; // UART Control Register |
localparam pUSR = 1; // UART Status Register |
localparam pTDR = 2; // Tx Data Register |
localparam pRDR = 3; // Rx Data Register |
localparam pSPR = 4; // Scratch Pad Register (and Aux. Status Regs) |
|
// TDR Bit Positions |
|
localparam pTFC = 11; // Tx FIFO Clear bit position |
localparam pRFC = 10; // Rx FIFO Clear bit position |
localparam pHLD = 9; // Tx SM Hold bit position |
|
// SPR Sub-Addresses |
|
localparam pRev = 1; // Revision Reg: {0, pVersion} |
localparam pLen = 2; // Length Reg: {0, pRF_Depth, pTF_Depth} |
localparam pFThr = 3; // Rx/Tx FIFO Thres:{0, RFThr[3:0], TFThr[3:0]} |
localparam pTHR = 4; // Tx Holding Reg: {0, THR[7:0]} |
localparam pRHR = 5; // Rx Holding Reg: {0, RHR[8:0]} |
localparam pTFCnt = 6; // Tx Count: {0, TFCnt[(pTF_Depth+4):0]} |
localparam pRFCnt = 7; // Rx Count: {0, RFCnt[(pRF_Depth+4):0]} |
|
// FIFO Configuration Parameters |
|
localparam pWidth = 8; // Maximum Character width |
localparam pxFThr = 8; // TF/RF Half-Full Flag Theshold (%, 4 bits) |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Local Signal Declarations |
// |
|
wire SCK; // Internal name for SSP_SCK |
|
wire [2:0] RSel; // Internal name for SSP_RA |
wire Sel_TDR; // Select - Transmit Data Register |
wire Sel_RDR; // Select - Receive Data Register |
wire Sel_UCR; // Select - UART Control Register |
wire Sel_SPR; // Select - Scratch Pad Register |
|
wire [7:0] TD, THR; // Transmit Data, Transmit Holding Register |
wire TFC; // TDR: Transmit FIFO Clear |
reg HLD; // TDR: Transmit Hold |
reg TxHold; // Transmit Hold, synchronized to Clk |
wire RE_THR; // Read Enable - Transmit Holding Register |
wire WE_THR, ClrTHR; // Write Enable - THR, Clear/Reset THR |
wire TF_FF, TF_EF, TF_HF; // Transmit FIFO Flags - Full, Empty, Half |
|
wire [8:0] RD, RHR; // Receive Data (In), Receive Holding Reg |
wire RFC; // TDR: Receive FIFO Clear |
wire WE_RHR; // Write Enable - RHR |
wire RE_RHR, ClrRHR; // Read Enable - RHR, Clear/Reset RHR |
wire RF_FF, RF_EF, RF_HF; // Receive FIFO Flags - Full, Empty, Half |
wire [(pTF_Depth + 4):0] TFCnt; // Tx FIFO Count |
wire [(pRF_Depth + 4):0] RFCnt; // RX FIFO Count |
|
reg [ 7:0] TDR; // Transmit Data Register |
// wire [11:0] RDR; // Receive Data Register, UART Status Reg |
reg [11:0] RDR; // Receive Data Register, UART Status Reg |
reg [11:0] UCR, USR, SPR; // UART Control, Status, & Scratch Pad Regs |
reg [ 7:0] RTFThr; // UART Rx/Tx FIFO Threshold Register |
|
wire [1:0] MD; // UCR: Operating Mode |
wire RTSo, IE; // UCR: RTS Output, Interrupt Enable |
wire [3:0] FMT; // UCR: Format (UCR[3:0] Reserved for Baud) |
|
reg Len, NumStop, ParEn; // Char Length, # Stop Bits, Parity Enable |
reg [1:0] Par; // Parity Selector |
reg [3:0] PS; // Baud Rate Prescaler |
reg [7:0] Div; // Baud Rate Divider |
reg [3:0] CCntVal; // RTO Character Length: {10 | 11 | 12} - 1 |
wire [3:0] RTOVal; // RTO Character Delay Value: (N - 1) |
|
wire RTSi, CTSi; // USR: RTS Input, CTS Input |
reg [1:0] RS, TS; // USR: Rcv Status, Xmt Status |
wire iRTO; // USR: Receive Timeout Interrupt |
wire iRHF; // USR: Receive Half Full Interrupt |
wire iTHE; // USR: Transmit Half Empty Interrupt |
wire iTFE; // USR: Transmit FIFO Empty Interrupt |
|
reg En; // delayed SSP_En (1 SCK period) |
wire Clr_Int; // Clear Interrupt Flags - read of USR |
|
wire WE_SPR; // Write Enable: Scratch Pad Register |
wire WE_RTFThr; // Write Enable: Rx/Tx FIFO Threshold Reg. |
reg [11:0] SPR_DO; // SPR Output Data |
|
wire TxD; // UART TxD Output (Mode Multiplexer Input) |
reg RxD; // UART RxD Input (Mode Multiplexer Output) |
|
wire TRDY; // RDR: Transmit Ready |
wire RRDY; // RDR: Receive Ready |
wire RTO; // RDR: Receive Timeout |
wire RERR; // RDR: Receive Error |
|
wire RcvTimeout; // Receive Timeout |
|
wire [7:0] Version = pVersion; |
wire [3:0] TFLen = pTF_Depth; // Len = (2**(pTF_Depth + 4)) |
wire [3:0] RFLen = pRF_Depth; |
wire [3:0] TFThr = pxFThr; // Thr = pxFThr ? pxFThr*(2**pTFLen) : 1 |
wire [3:0] RFThr = pxFThr; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
assign SCK = SSP_SCK; |
|
// Assign SSP Read/Write Strobes |
|
assign SSP_WE = SSP_SSEL & SSP_WnR & SSP_EOC; |
assign SSP_RE = SSP_SSEL & ~SSP_WnR & SSP_EOC; |
|
// Break out Register Select Address |
|
assign RSel = SSP_RA; |
|
assign Sel_TDR = (RSel == pTDR); |
assign Sel_RDR = (RSel == pRDR); |
assign Sel_USR = (RSel == pUSR); |
assign Sel_UCR = (RSel == pUCR); |
assign Sel_SPR = (RSel == pSPR); |
|
// Assign SPR Data Output based on sub-addresses: SPR[11:9] |
|
always @(*) |
begin |
case(SPR[11:9]) |
pRev : SPR_DO <= {4'b0, Version[7:0]}; |
pLen : SPR_DO <= {4'b0, pRF_Depth[3:0], pTF_Depth[3:0]}; |
pFThr : SPR_DO <= {4'b0, RTFThr}; |
pTHR : SPR_DO <= {4'b0, THR}; |
pRHR : SPR_DO <= {3'b0, RHR}; |
pTFCnt : SPR_DO <= {1'b0, TFCnt[(pTF_Depth + 4):0]}; |
pRFCnt : SPR_DO <= {1'b0, RFCnt[(pRF_Depth + 4):0]}; |
default : SPR_DO <= SPR; |
endcase |
end |
|
// Drive SSP Output Data Bus |
|
always @(*) |
begin |
case(RSel) |
pUCR : SSP_DO <= ((SSP_SSEL) ? UCR : 0); |
pUSR : SSP_DO <= ((SSP_SSEL) ? USR : 0); |
pTDR : SSP_DO <= ((SSP_SSEL) ? TDR : 0); |
pRDR : SSP_DO <= ((SSP_SSEL) ? RDR : 0); |
pSPR : SSP_DO <= ((SSP_SSEL) ? SPR_DO : 0); |
default : SSP_DO <= ((SSP_SSEL) ? {1'b0, RFCnt[(pRF_Depth+4) : 0]} : 0); |
endcase |
end |
|
// Assert IRQ when IE is set |
|
assign Rst_IRQ = Rst | Clr_Int; |
|
always @(posedge Clk) |
begin |
if(Rst_IRQ) |
IRQ <= 0; |
else if(~IRQ) |
IRQ <= #1 IE & (iTFE | iTHE | iRHF | iRTO); |
end |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Write UART Control Register |
// |
|
always @(negedge SCK or posedge Rst) |
begin |
if(Rst) |
UCR <= #1 0; |
else if(Sel_UCR) |
UCR <= #1 ((SSP_WE) ? SSP_DI : USR); |
end |
|
// Assign UCR Fields |
|
assign MD = UCR[11:10]; |
assign RTSo = UCR[9]; |
assign IE = UCR[8]; |
assign FMT = UCR[7:4]; |
|
// Format Decode |
|
always @(FMT) |
case(FMT) |
4'b0000 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0001 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0010 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b00}; // 8O1 |
4'b0011 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b01}; // 8E1 |
4'b0100 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b10}; // 8S1 |
4'b0101 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b11}; // 8M1 |
4'b0110 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0111 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b0, 2'b00}; // 8N2 |
4'b1000 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b00}; // 8O2 |
4'b1001 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b01}; // 8E2 |
4'b1010 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b10}; // 8S2 |
4'b1011 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b11}; // 8M2 |
4'b1100 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b0, 1'b1, 2'b00}; // 7O1 |
4'b1101 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b0, 1'b1, 2'b01}; // 7E1 |
4'b1110 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b1, 1'b1, 2'b00}; // 7O2 |
4'b1111 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b1, 1'b1, 2'b01}; // 7E2 |
endcase |
|
// Baud Rate Generator's PS and Div for defined Baud Rates (48 MHz Osc) |
// |
// Profibus Baud Rates |
// |
// {PS, Div} <= {4'h0, 8'h00}; // PS= 1; Div= 1; BR=3.0M |
// {PS, Div} <= {4'h0, 8'h01}; // PS= 1; Div= 2; BR=1.5M |
// {PS, Div} <= {4'h0, 8'h05}; // PS= 1; Div= 6; BR=500.0k |
// {PS, Div} <= {4'h0, 8'h0F}; // PS= 1; Div= 16; BR=187.5k |
// |
// Standard Baud Rates |
// |
// {PS, Div} <= {4'hC, 8'h00}; // PS=13; Div= 1; BR=230.4k |
// {PS, Div} <= {4'hC, 8'h01}; // PS=13; Div= 2; BR=115.2k |
// {PS, Div} <= {4'hC, 8'h02}; // PS=13; Div= 3; BR= 76.8k |
// {PS, Div} <= {4'hC, 8'h03}; // PS=13; Div= 4; BR= 57.6k |
// {PS, Div} <= {4'hC, 8'h05}; // PS=13; Div= 6; BR= 38.4k |
// {PS, Div} <= {4'hC, 8'h07}; // PS=13; Div= 8; BR= 28.8k |
// {PS, Div} <= {4'hC, 8'h0B}; // PS=13; Div= 12; BR= 19.2k |
// {PS, Div} <= {4'hC, 8'h0F}; // PS=13; Div= 16; BR= 14.4k |
// {PS, Div} <= {4'hC, 8'h17}; // PS=13; Div= 24; BR= 9.6k |
// {PS, Div} <= {4'hC, 8'h2F}; // PS=13; Div= 48; BR= 4.8k |
// {PS, Div} <= {4'hC, 8'h5F}; // PS=13; Div= 96; BR= 2.4k |
// {PS, Div} <= {4'hC, 8'hBF}; // PS=13; Div=192; BR= 1.2k |
// |
// Baud Rate Generator's PS and Div for defined Baud Rates (29.4912 MHz) |
// |
// Extended Baud Rates |
// |
// {PS, Div} <= {4'h0, 8'h00}; // PS= 1; Div= 1; BR=1843.2k |
// {PS, Div} <= {4'h0, 8'h01}; // PS= 1; Div= 2; BR= 921.6k |
// {PS, Div} <= {4'h0, 8'h02}; // PS= 1; Div= 3; BR= 614.4k |
// {PS, Div} <= {4'h0, 8'h03}; // PS= 1; Div= 4; BR= 460.8k |
// {PS, Div} <= {4'h0, 8'h05}; // PS= 1; Div= 6; BR= 307.2k |
// {PS, Div} <= {4'h0, 8'h07}; // PS= 1; Div= 8; BR= 230.4k |
// {PS, Div} <= {4'h0, 8'h0B}; // PS= 1; Div= 12; BR= 153.6k |
// |
// Standard Baud Rates |
// |
// {PS, Div} <= {4'h0, 8'h0F}; // PS= 1; Div= 16; BR= 115.2k |
// {PS, Div} <= {4'h0, 8'h17}; // PS= 1; Div= 24; BR= 76.8k |
// {PS, Div} <= {4'h0, 8'h1F}; // PS= 1; Div= 32; BR= 57.6k |
// {PS, Div} <= {4'h0, 8'h2F}; // PS= 1; Div= 48; BR= 38.4k |
// {PS, Div} <= {4'h0, 8'h3F}; // PS= 1; Div= 64; BR= 28.8k |
// {PS, Div} <= {4'h0, 8'h5F}; // PS= 1; Div= 96; BR= 19.2k |
// {PS, Div} <= {4'h0, 8'h7F}; // PS= 1; Div=128; BR= 14.4k |
// {PS, Div} <= {4'h0, 8'hBF}; // PS= 1; Div=192; BR= 9.6k |
// {PS, Div} <= {4'h0, 8'hFF}; // PS= 1; Div=256; BR= 7.2k |
// {PS, Div} <= {4'h1, 8'hBF}; // PS= 2; Div=192; BR= 4.8k |
// {PS, Div} <= {4'h1, 8'hFF}; // PS= 3; Div=256; BR= 3.6k |
// {PS, Div} <= {4'h3, 8'hBF}; // PS= 4; Div=192; BR= 2.4k |
// {PS, Div} <= {4'h3, 8'hFF}; // PS= 4; Div=256; BR= 1.8k |
// {PS, Div} <= {4'h7, 8'hBF}; // PS= 8; Div=192; BR= 1.2k |
// {PS, Div} <= {4'h7, 8'hFF}; // PS= 8; Div=256; BR= 0.9k |
// {PS, Div} <= {4'hF, 8'hBF}; // PS=16; Div=192; BR= 0.6k |
// {PS, Div} <= {4'hF, 8'hFF}; // PS=16; Div=256; BR= 0.45k |
|
// Receive Timeout Character Frame Length |
|
always @(FMT) |
case(FMT) |
4'b0000 : CCntVal <= 4'h9; // 8N1, 9 <= 10 - 1 |
4'b0001 : CCntVal <= 4'h9; // 8N1, 9 <= 10 - 1 |
4'b0010 : CCntVal <= 4'hA; // 8O1, 10 <= 11 - 1 |
4'b0011 : CCntVal <= 4'hA; // 8E1, 10 <= 11 - 1 |
4'b0100 : CCntVal <= 4'hA; // 8S1, 10 <= 11 - 1 |
4'b0101 : CCntVal <= 4'hA; // 8M1, 10 <= 11 - 1 |
4'b0110 : CCntVal <= 4'h9; // 8N1, 9 <= 10 - 1 |
4'b0111 : CCntVal <= 4'hA; // 8N2, 10 <= 11 - 1 |
4'b1000 : CCntVal <= 4'hB; // 8O2, 11 <= 12 - 1 |
4'b1001 : CCntVal <= 4'hB; // 8E2, 11 <= 12 - 1 |
4'b1010 : CCntVal <= 4'hB; // 8S2, 11 <= 12 - 1 |
4'b1011 : CCntVal <= 4'hB; // 8M2, 11 <= 12 - 1 |
4'b1100 : CCntVal <= 4'h9; // 7O1, 9 <= 10 - 1 |
4'b1101 : CCntVal <= 4'h9; // 7E1, 9 <= 10 - 1 |
4'b1110 : CCntVal <= 4'h9; // 7O2, 9 <= 10 - 1 |
4'b1111 : CCntVal <= 4'h9; // 7E2, 9 <= 10 - 1 |
endcase |
|
assign RTOVal = (pRTOChrDlyCnt - 1); // Set RTO Character Delay Count |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// USR Register and Operations |
// |
|
always @(*) |
begin |
case({RF_FF, RF_HF, RF_EF}) |
3'b000 : RS <= 2'b01; // Not Empty, < Half Full |
3'b001 : RS <= 2'b00; // Empty |
3'b010 : RS <= 2'b10; // > Half Full, < Full |
3'b011 : RS <= 2'b00; // Not Possible/Not Allowed |
3'b100 : RS <= 2'b00; // Not Possible/Not Allowed |
3'b101 : RS <= 2'b00; // Not Possible/Not Allowed |
3'b110 : RS <= 2'b11; // Full |
3'b111 : RS <= 2'b00; // Not Possible/Not Allowed |
endcase |
end |
|
always @(*) |
begin |
case({TF_FF, TF_HF, TxIdle}) |
3'b000 : TS <= 2'b01; // Not Empty, < Half Full |
3'b001 : TS <= 2'b00; // Empty |
3'b010 : TS <= 2'b10; // > Half Full, < Full |
3'b011 : TS <= 2'b00; // Not Possible/Not Allowed |
3'b100 : TS <= 2'b00; // Not Possible/Not Allowed |
3'b101 : TS <= 2'b00; // Not Possible/Not Allowed |
3'b110 : TS <= 2'b11; // Full |
3'b111 : TS <= 2'b00; // Not Possible/Not Allowed |
endcase |
end |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
USR <= #1 0; |
else |
USR <= #1 {MD, RTSi, CTSi, RS, TS, iRTO, iRHF, iTHE, iTFE}; |
end |
|
// Read UART Status Register |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
En <= #1 0; |
else |
En <= #1 SSP_En; |
end |
|
// Generate Clr_Int on rising edge of SSP_En if Sel_USR asserted |
// and rising edge on SSP_En and any interrupt flags set in USR |
// change clock domains from SCK to Clk (UART) |
|
re1ce RED1 ( |
.den(Sel_USR & (SSP_En & ~En) & |USR[3:0]), |
.din(SCK), |
.clk(Clk), |
.rst(Rst), |
.trg(), |
.pls(Clr_Int) |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// BRR - Baud Rate Register |
// |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
{PS, Div} <= #1 {pPS_Default, pDiv_Default}; // Default: 9600 bps |
else if(Sel_USR) |
{PS, Div} <= #1 ((SSP_WE) ? SSP_DI : {PS, Div}); |
end |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDR/RDR Registers and Operations |
// |
|
// Write Transmit Data Register |
|
assign WE_TDR = SSP_WE & Sel_TDR & TRDY; |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
TDR <= #1 8'b0; |
else if(WE_TDR) |
TDR <= #1 SSP_DI[7:0]; |
end |
|
assign TD = TDR; |
|
// Clear Transmit Holding Register |
|
assign TFC = SSP_DI[pTFC] & WE_TDR; |
|
re1ce RED2 ( |
.den(TFC), |
.din(SCK), |
.clk(Clk), |
.rst(Rst), |
.trg(), |
.pls(ClrTHR) |
); |
|
// Clear Receive Holding Register |
|
assign RFC = SSP_DI[pRFC] & WE_TDR; |
|
re1ce RED3 ( |
.den(RFC), |
.din(SCK), |
.clk(Clk), |
.rst(Rst), |
.trg(), |
.pls(ClrRHR) |
); |
|
// Latch/Register the Transmit Hold Bit on writes to TDR |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
HLD <= #1 0; |
else if(WE_TDR) |
HLD <= #1 SSP_DI[pHLD]; |
end |
|
// Write Transmit Holding Register (FIFO) |
|
re1ce RED4 ( |
.den(WE_TDR), |
.din(SCK), |
.clk(Clk), |
.rst(Rst), |
.trg(), |
.pls(WE_THR) |
); |
|
// Set TxHold when the THR is written |
|
always @(posedge Clk) |
begin |
if(Rst) |
TxHold <= #1 0; |
else if(WE_THR) |
TxHold <= #1 HLD; |
end |
|
// Read Receive Data Register |
|
assign TRDY = ~TF_FF; |
assign RRDY = ~RF_EF; |
assign RTO = RcvTimeout; |
assign RERR = RHR[8]; |
|
// Capture and Hold Receive Data Register on SCK clock domain |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
RDR <= #1 0; |
else if(~SSP_En) |
RDR <= #1 {TRDY, RRDY, RTO, RERR, RHR[7:0]}; |
end |
|
// Read Receive Holding Register |
// Generate RE_RHR read pulse only when the captured value indicates that |
// RDR contains data because there is data in the Receive FIFO, i.e. RHR. |
|
assign RE_RDR = Sel_RDR & ~SSP_WnR & (SSP_En & ~En) & RDR[10]; |
|
re1ce RED5 ( |
.den(RE_RDR), |
.din(SCK), |
.clk(Clk), |
.rst(Rst), |
.trg(), |
.pls(RE_RHR) |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Write Scratch Pad Register |
// |
|
assign WE_SPR = SSP_WE & Sel_SPR; |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
SPR <= #1 0; |
else if(WE_SPR) |
SPR <= #1 SSP_DI; |
end |
|
assign WE_RTFThr = SSP_WE & Sel_SPR & (SSP_DI[11:9] == pFThr) & SSP_DI[8]; |
|
always @(posedge SCK or posedge Rst) |
begin |
if(Rst) |
RTFThr <= #1 {RFThr, TFThr}; |
else if(WE_RTFThr) |
RTFThr <= #1 SSP_DI; |
end |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Xmt/Rcv Holding Register Instantiations - Dual-Port Synchronous FIFOs |
// |
// THR FIFO - 2**(pTFLen + 4) x pWidth FIFO |
|
DPSFnmCE #( |
.addr((pTF_Depth + 4)), |
.width(pWidth), |
.init(pTF_Init) |
) TF1 ( |
.Rst(Rst | ClrTHR), |
.Clk(Clk), |
.WE(WE_THR), |
.RE(RE_THR), |
.DI(TD), |
.DO(THR), |
.FF(TF_FF), |
.HF(TF_HF), |
.EF(TF_EF), |
.Cnt(TFCnt) |
); |
|
// RHR FIFO - 2**(pRFLen + 4) x (pWidth + 1) FIFO |
|
DPSFnmCE #( |
.addr((pRF_Depth + 4)), |
.width((pWidth + 1)), |
.init(pRF_Init) |
) RF1 ( |
.Rst(Rst | ClrRHR), |
.Clk(Clk), |
.WE(WE_RHR), |
.RE(RE_RHR), |
.DI(RD), |
.DO(RHR), |
.FF(RF_FF), |
.HF(RF_HF), |
.EF(RF_EF), |
.Cnt(RFCnt) |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Configure external/internal serial port signals according to MD[1:0] |
// MD[1:0] = 0,1 - RS-233; 2,3 - RS-485 |
|
assign RS232 = ~MD[1]; |
assign RS485 = MD[1]; |
|
// Set RS-232/Rs-485 TxD |
|
assign TxD_232 = (RS232 ? TxD : 1); |
assign TxD_485 = (RS485 ? TxD : 1); |
|
// Assert DE in the RS-485 modes whenever the TxSM is not idle, and deassert |
// whenever the RS-485 modes are not selected |
|
assign xDE = (RS485 ? ~TxIdle : 0); |
|
// Connect the UART's RxD serial input to the appropriate external RxD input |
// Hold RxD to logic 1 when in the RS-485 w/o Loopback mode and the TxSM |
// is transmitting data. In this manner, the external xOE signal to the |
// RS-485 transceiver can always be asserted. |
|
always @(posedge Clk or posedge Rst) |
begin |
if(Rst) |
RxD <= #1 1; |
else |
case(MD) |
2'b00 : RxD <= #1 RxD_232; |
2'b01 : RxD <= #1 RxD_232; |
2'b10 : RxD <= #1 (TxIdle ? RxD_485 : 1); |
2'b11 : RxD <= #1 RxD_485; |
endcase |
end |
|
// RS-232 auto-Handshaking is implemented as Ready-To-Receive (RTR) based on |
// the Rcv FIFO flag settings. xRTS, which should connect to the receiving |
// side's xCTS, is asserted whenever the local receive FIFO is less than |
// half full. If a similar UART with hardware handshaking is connected, |
// then that transmitter should stop sending until the local FIFO is read |
// so that it is below the HF mark. Since local reads of the receive FIFO |
// are expected to be much faster than the RS-232 baud rate, it is not |
// expected that hysteresis will be required to prevent rapid assertion |
// and deassertion of RTS. |
// |
// This handshaking mechanism was selected for the automatic handshaking |
// mode because it prevents (or attempts to prevent) receive FIFO over- |
// flow in the receiver. Furthermore, it reduces the software workload in |
// the transmitter's send routines. |
// |
// For all other modes, the CTSi control signal to the UART_TXSM is held |
// at logic one. This effectively disables the TxSM's handshaking logic, |
// and allows the transmitter to send data as soon as data is written to |
// Xmt FIFO. |
|
always @(*) |
begin |
case(MD) |
2'b00 : xRTS <= RTSo; |
2'b01 : xRTS <= ~RF_HF; |
2'b10 : xRTS <= 0; |
2'b11 : xRTS <= 0; |
endcase |
end |
|
assign RTSi = ((RS232) ? xRTS : xDE); |
assign CTSi = ((MD == 1) ? xCTS : 1); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// UART Baud Rate Generator Instantiation |
// |
|
UART_BRG BRG ( |
.Rst(Rst), |
.Clk(Clk), |
.PS(PS), |
.Div(Div), |
.CE_16x(CE_16x) |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// UART Transmitter State Machine & Shift Register Instantiation |
// |
|
UART_TXSM XMT ( |
.Rst(Rst), |
.Clk(Clk), |
|
.CE_16x(CE_16x), |
|
.Len(Len), |
.NumStop(NumStop), |
.ParEn(ParEn), |
.Par(Par), |
|
.TF_RE(RE_THR), |
.THR(THR), |
.TF_EF(TF_EF | TxHold), |
|
.TxD(TxD), |
.CTSi(CTSi), |
|
.TxIdle(TxIdle), |
.TxStart(), |
.TxShift(), |
.TxStop() |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// UART Receiver State Machine & Shift Register Instantiation |
// |
|
UART_RXSM RCV ( |
.Rst(Rst), |
.Clk(Clk), |
|
.CE_16x(CE_16x), |
|
.Len(Len), |
.NumStop(NumStop), |
.ParEn(ParEn), |
.Par(Par), |
|
.RxD(RxD), |
|
.RD(RD), |
.WE_RHR(WE_RHR), |
|
.RxWait(), |
.RxIdle(RxIdle), |
.RxStart(), |
.RxShift(), |
.RxParity(), |
.RxStop(), |
.RxError() |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// UART Receive Timeout Module Instantiation |
// |
|
UART_RTO TMR ( |
.Rst(Rst), |
.Clk(Clk), |
|
.CE_16x(CE_16x), |
|
.WE_RHR(WE_RHR), |
.RE_RHR(RE_RHR), |
|
.CCntVal(CCntVal), |
.RTOVal(RTOVal), |
|
.RcvTimeout(RcvTimeout) |
); |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// UART Interrupt Generator Instantiation |
// |
|
UART_INT INT ( |
.Rst(Rst), |
.Clk(Clk), |
|
.TF_HF(TF_HF), |
.TF_EF(TF_EF), |
.RF_HF(RF_HF), |
.RF_EF(RF_EF), |
|
.RTO(RTO), |
|
.Clr_Int(Clr_Int), |
.USR(USR[3:0]), |
|
.iTFE(iTFE), |
.iTHE(iTHE), |
.iRHF(iRHF), |
.iRTO(iRTO) |
); |
|
endmodule |
/trunk/RTL/redet.v
0,0 → 1,94
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2006-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
////////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 11:45:29 12/31/2006 |
// Design Name: USB MBP HDL |
// Module Name: re1ce |
// Project Name: USBMBP_HDL |
// Target Devices: XC2S15-5TQ144 |
// Tool versions: ISE Webpack 8.2i |
// Description: Multi-stage synchronizer with rising edge detection |
// |
// Dependencies: None |
// |
// Revision History: |
// |
// 0.01 06L31 MAM File Created |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module redet(rst, clk, din, pls); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Port Declarations |
// |
|
input rst; |
input clk; |
input din; |
output pls; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Level Declarations |
// |
|
reg [2:0] QSync; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
always @(posedge clk or posedge rst) begin |
if(rst) |
#1 QSync <= 3'b0; |
else |
#1 QSync <= {QSync[0] & ~QSync[1], QSync[0], din}; |
end |
assign pls = QSync[2]; |
|
endmodule |
/trunk/RTL/UART_RF.coe
0,0 → 1,128
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
/trunk/RTL/UART_RXSM.v
0,0 → 1,332
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 08:44:44 05/31/2008 |
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/UART_RXSM.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This module implements the SSP UART Receive State Machine |
// |
// Dependencies: None |
// |
// Revision History: |
// |
// 0.01 08E31 MAM File Created |
// |
// 1.00 08F08 MAM Module Released |
// |
// 1.01 08F12 MAM Pulled Format Decoder ROM and added its outputs to |
// the port list. Allows greater format specification |
// flexibility. 7-bit formats require parity. If ParEn |
// is not set, the parity will be tested according to |
// the settings of the Par bits, which may result in |
// anomalous behavior. |
// |
// 2.00 11B06 MAM Converted to Verilog 2001. |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module UART_RXSM( |
input Rst, |
input Clk, |
|
input CE_16x, // 16x Clock Enable - Baud Rate x16 |
|
input Len, // Word length: 0 - 8-bits; 1 - 7 bits |
input NumStop, // Number Stop Bits: 0 - 1 Stop; 1 - 2 Stop |
input ParEn, // Parity Enable |
input [1:0] Par, // 0 - Odd; 1 - Even; 2 - Space (0); 3 - Mark (1) |
|
input RxD, // Input Asynchronous Serial Receive Data |
|
output reg [8:0] RD, // Receive Data Output - bit 8 = Rcv Error (RERR) |
output reg WE_RHR, // Write Enable - Receive Holding Register |
|
output RxWait, // RxSM - Wait State |
output RxIdle, // RxSM - Idle State |
output RxStart, // RxSM - Start Bit Check State |
output RxShift, // RxSM - RxD Shift State |
output RxParity, // RxSM - RxD Parity Shift State |
output RxStop, // RxSM - RxD Stop Bit Check States |
output RxError // RxSM - Error State |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Parameters |
// |
|
// Receive State Machine Declarations (Binary) |
|
localparam pWaitMark = 0; |
localparam pChkMark = 1; |
localparam pIdle = 3; |
localparam pChkStart = 2; |
localparam pShift0 = 10; |
localparam pShift1 = 11; |
localparam pShift2 = 9; |
localparam pShift3 = 8; |
localparam pShift4 = 12; |
localparam pShift5 = 13; |
localparam pShift6 = 15; |
localparam pShift7 = 14; |
localparam pChkStop1 = 6; |
localparam pChkStop2 = 7; |
localparam pChkParity = 5; |
localparam pRcvError = 4; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Local Signal Declarations |
// |
|
(* FSM_ENCODING="SEQUENTIAL", |
SAFE_IMPLEMENTATION="YES", |
SAFE_RECOVERY_STATE="4'b0" *) reg [3:0] RxSM = pWaitMark; |
|
reg [3:0] BCnt; |
reg [7:0] RSR; |
|
reg Err; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// RxSM Decode |
// |
|
assign RxSM_Wait = ( (RxSM == pWaitMark) |
| (RxSM == pChkMark) |
| (RxSM == pIdle) |
| (RxSM == pRcvError) ); |
|
assign RxWait = RxSM_Wait; |
assign RxIdle = (RxSM == pIdle); |
assign RxStart = (RxSM == pChkStart); |
assign RxShift = ( (RxSM == pShift0) |
| (RxSM == pShift1) |
| (RxSM == pShift2) |
| (RxSM == pShift3) |
| (RxSM == pShift4) |
| (RxSM == pShift5) |
| (RxSM == pShift6) |
| (RxSM == pShift7) ); |
assign RxParity = (RxSM == pChkParity); |
assign RxStop = (RxSM == pChkStop1) | (RxSM == pChkStop2); |
assign RxError = (RxSM == pRcvError); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Bit Rate Prescaler |
// |
// Prescaler is held in the half-bit load state during reset and when the |
// RXSM is in the RxSM_Wait states. As a consequence, the first overflow |
// is only half a bit period, and only occurs in the pChkStart state. |
// Subsequent, overflows are occur once per bit period in the middle of |
// each of the remaining bits. |
// |
|
assign Rst_BCnt = Rst | RxSM_Wait; |
|
always @(posedge Clk) |
begin |
if(Rst_BCnt) |
BCnt <= #1 4'b1000; |
else if(CE_16x) |
BCnt <= #1 BCnt + 1; |
end |
|
assign TC_BCnt = CE_16x & (BCnt == 4'b1111); |
|
/////////////////////////////////////////////////////////////////////////////// |
|
assign CE_RxSM = (RxSM_Wait ? CE_16x : TC_BCnt); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Receive Shift Register |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
RSR <= #1 8'b0; |
else if(CE_RxSM) |
case(RxSM) |
pChkStart : RSR <= #1 8'b0; |
pShift0 : RSR[0] <= #1 RxD; |
pShift1 : RSR[1] <= #1 RxD; |
pShift2 : RSR[2] <= #1 RxD; |
pShift3 : RSR[3] <= #1 RxD; |
pShift4 : RSR[4] <= #1 RxD; |
pShift5 : RSR[5] <= #1 RxD; |
pShift6 : RSR[6] <= #1 RxD; |
pShift7 : RSR[7] <= #1 RxD; |
default : RSR <= #1 RSR; |
endcase |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Parity Checker |
// if not Check Parity State, then ParErr = 0 |
// |
|
assign OddPar = ^{RxD, RSR}; |
assign EvnPar = ~OddPar; |
|
always @(*) |
begin |
case(Par) |
2'b00 : Err <= ~OddPar; |
2'b01 : Err <= ~EvnPar; |
2'b10 : Err <= RxD; |
2'b11 : Err <= ~RxD; |
endcase |
end |
|
assign ParErr = Err & (RxSM == pChkParity); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Receive Holding Register Data |
// |
|
assign CE_RD = CE_RxSM & (((RxSM == pChkStop1) & RxD) | (RxSM == pRcvError)); |
|
always @(posedge Clk) |
begin |
if(Rst) |
RD <= #1 9'b0; |
else if(CE_RD) |
RD <= #1 {(RxSM == pRcvError), RSR}; |
end |
|
always @(posedge Clk) |
begin |
if(Rst) |
WE_RHR <= #1 1'b0; |
else |
WE_RHR <= #1 CE_RD; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// RxSM - Receive State Machine |
// |
// The Receive State Machine starts in the WaitMark state to insure that |
// the receive line is in the marking state before continuing. The ChkMark |
// state validates that the receive line is in the marking state. If it |
// is, then the RxSM is adanced to the Idle state to wait for the start |
// bit. Otherwise, RxSM returns to the WaitMark state to wait for the line |
// to return to the marking (idle) state. |
// |
// The format is processed through the receive sequence. The length, |
// parity options, and the number of stop bits determine the state tran- |
// sitions that the RxSM makes. A parity or a framing error is simply |
// recorded as an error with the 9th bit of the receive holding register. |
// Line break conditions, invalid stop bits, etc. are handled through the |
// pRcvError and the pWaitMark states. Thus, line break conditions are not |
// expected to cause the RxSM to receive more than one character, and the |
// pWaitMark state holds the receiver in a wait state until the line |
// returns to the marking (idle) state. |
// |
|
always @(posedge Clk) |
begin |
if(Rst) |
RxSM <= #1 pWaitMark; |
else if(CE_RxSM) |
case(RxSM) |
pWaitMark : RxSM <= #1 ( RxD ? pChkMark |
: pWaitMark); |
|
pChkMark : RxSM <= #1 ( RxD ? pIdle |
: pWaitMark); |
|
pIdle : RxSM <= #1 (~RxD ? pChkStart |
: pIdle); |
|
pChkStart : RxSM <= #1 ( RxD ? pIdle |
: pShift0); |
|
pShift0 : RxSM <= #1 pShift1; |
pShift1 : RxSM <= #1 pShift2; |
pShift2 : RxSM <= #1 pShift3; |
pShift3 : RxSM <= #1 pShift4; |
pShift4 : RxSM <= #1 pShift5; |
pShift5 : RxSM <= #1 pShift6; |
|
pShift6 : RxSM <= #1 (Len ? pChkParity |
: pShift7); |
|
pShift7 : RxSM <= #1 (ParEn ? pChkParity |
: (NumStop ? pChkStop2 |
: pChkStop1)); |
|
pChkParity : RxSM <= #1 (ParErr ? pRcvError |
: (NumStop ? pChkStop2 |
: pChkStop1)); |
|
pChkStop2 : RxSM <= #1 (RxD ? pChkStop1 |
: pRcvError); |
|
pChkStop1 : RxSM <= #1 (RxD ? pIdle |
: pRcvError); |
|
pRcvError : RxSM <= #1 pWaitMark; |
|
default : RxSM <= #1 pWaitMark; |
endcase |
end |
|
endmodule |
/trunk/RTL/UART_TF.coe
0,0 → 1,16
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
/trunk/RTL/UART_BRG.v
0,0 → 1,152
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 13:28:23 05/10/2008 |
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/UART_BRG.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This module implements the Baud Rate Generator for the SSP |
// UART described for the 1700-0403 MicroBridge Option Card. |
// |
// The Baud Rate Generator implements the 16 baud rates defined |
// in Table 3 of the SSP UART Specification. |
// |
// Dependencies: |
// |
// Revision History: |
// |
// 0.01 08E10 MAM File Created |
// |
// 1.00 08E10 MAM Initial Release |
// |
// 1.10 08E13 MAM Changed interface so Prescaler and Divider values |
// passed directly in by removing Baud Rate ROM. |
// |
// 1.11 08E14 MAM Reduced width of divider from 10 to 8 bits. |
// |
// 1.20 08E15 MAM Changed the structure of the PSCntr and Divider |
// to use a multiplxer on the input to load or count |
// which results in a more efficient implementation. |
// Added a registered TC on the PSCntr which functions |
// to break the combinatorial logic chains and speed |
// counter implementations. |
// |
// 1.30 08G26 MAM Corrected initial condition of the PSCntr, which |
// caused the prescaler to always divide by two. |
// Removed FF in PSCntr TC path to remove the divide |
// by two issue. CE_16x output remains as registered. |
// |
// 2.00 11B06 MAM Converted to Verilog 2001. |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module UART_BRG( |
input Rst, |
input Clk, |
|
input [3:0] PS, // Baud Rate Generator Prescaler Load Value |
input [7:0] Div, // Baud Rate Generator Divider Load Value |
|
output reg CE_16x // Clock Enable Output - 16x Baud Rate Output |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Local Signal Declarations |
// |
|
reg [ 3:0] PSCntr; // BRG Prescaler |
reg [ 7:0] Divider; // BRG Divider |
|
wire TC_PSCntr; // BRG Prescaler TC/Divider CE |
wire TC_Divider; // BRG Divider TC |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
// BRG Prescaler Counter |
|
always @(posedge Clk) |
begin |
if(Rst) |
PSCntr <= #1 0; |
else if(TC_PSCntr) |
PSCntr <= #1 PS; |
else |
PSCntr <= #1 PSCntr - 1; |
end |
|
assign TC_PSCntr = (PSCntr == 0); |
|
// BRG Divider |
|
always @(posedge Clk) |
begin |
if(Rst) |
Divider <= #1 0; |
else if(TC_Divider) |
Divider <= #1 Div; |
else if(TC_PSCntr) |
Divider <= #1 Divider - 1; |
end |
|
assign TC_Divider = TC_PSCntr & (Divider == 0); |
|
// Output 16x Bit Clock/CE |
|
always @(posedge Clk) |
begin |
if(Rst) |
CE_16x <= #1 1'b0; |
else |
CE_16x <= #1 TC_Divider; |
end |
|
endmodule |
/trunk/RTL/UART_INT.v
0,0 → 1,227
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 09:37:34 06/15/2008 |
/// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/UART_INT.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: |
// |
// This module implements the interrupt request logic for the SSP UART. Inter- |
// rupt requests are generated for four conditions: |
// |
// (1) Transmit FIFO Empty; |
// (2) Transmit FIFO Half Empty; |
// (3) Receive FIFO Half Full; |
// (4) and Receive Timeouts. |
// |
// These four conditions are used as the interrupt sources. Interrupts are not |
// generated for CTS Change-Of-State and Rx Errors because that information is |
// either not useful (CTS) or reported for each received character (RERR). The |
// interrupt flags generated by this module must be combined externally to form |
// an interrupt request to the client. |
// |
// The interrupt flags will be reset/cleared as indicated below except when the |
// rst/clr pulse is coincident with the pulse which would set the flag, the |
// flag remains set so that the new assertion pulse is not lost. |
// |
// There remains a small probability that the second pulse may be lost. This |
// can be remedied by stretching the setting pulse to a width equal to the un- |
// certainty between the setting and resetting pulses: approximately 4 clock |
// cycles when re1ce modules are used to generate the Clr_Int pulse. |
// |
// Dependencies: redet.v, fedet.v |
// |
// Revision History: |
// |
// 0.01 08E15 MAM File Created |
// |
// 1.00 08G24 MAM Corrected the reset function for the four flags. |
// The previous implementation would not reset or |
// allow the flags to be initialized to the "Off" |
// state. Added the RF_EF as a port, and added a |
// rising edge detector on the RF_EF to reset the |
// RTO flag. |
// |
// 1.10 08H10 MAM Changed the reset logic for the iTFE and iTHF |
// so that they remain set until read by the host. |
// |
// 2.00 11B06 MAM Converted to Verilog 2001. |
// |
// 2.10 13G12 MAM Corrected an error regarding the clearing of the |
// interrupt flag bits. Required a change to the |
// USR in module SSP_UART: USR needed to be registered |
// whenever a read operation was performed. The result- |
// ing difference between the interrupt flags in the |
// UART clock domain, and the corresponding USR bits in |
// the SCK domain preserve the interrupt bits until the |
// user has had a chance to read the interrupt flag. |
// Also renamed to iRDA flag to iRHF which is more |
// appropriate since the flag is set only on the rising |
// edge of the RX FIFO Half Full flag. |
// |
// Additional Comments: |
// |
// The interrupt flags are set and reset under a variety of conditions. |
// |
// iTFE - Set on the rising edge of the Transmit FIFO Empty Flag (TF_EF) |
// Rst on Clr_Int. |
// |
// iTHE - Set on the falling edge of Transmit FIFO Half Full (TF_HF) |
// Rst on Clr_Int. |
// |
// iRHF - Set on the rising edge of Receive FIFO Half Full (RF_HF) |
// Rst on Clr_Int or on the falling edge of RF_HF. |
// |
// iRTO - Set on the rising edge of RTO |
// Rst on Clr_Int. |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module UART_INT( |
input Rst, // Reset |
input Clk, // Clock |
|
input TF_HF, // Transmit FIFO Half-Full Flag |
input TF_EF, // Transmit FIFO Empty Flag |
input RF_HF, // Receive FIFO Half-Full Flag |
input RF_EF, // Receive FIFO Empty Flag |
|
input RTO, // Receiver Timeout |
|
input Clr_Int, // Clear interrupt pulse |
input [3:0] USR, // USR: {iRTO, iRHF, iTHE, iTFE} |
|
output reg iTFE, // Interrupt - Tx FIFO Empty |
output reg iTHE, // Interrupt - Tx FIFO Half Empty |
output reg iRHF, // Interrupt - Rx FIFO Half Full |
output reg iRTO // Interrupt - Receive Time Out Detected |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Local Signal Declarations |
// |
|
wire reTF_EF, feTF_HF; |
wire reRF_HF, feRF_HF, reRF_EF; |
wire reRTO; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
redet RE1 (.rst(Rst), .clk(Clk), .din(TF_EF), .pls(reTF_EF)); |
fedet FE1 (.rst(Rst), .clk(Clk), .din(TF_HF), .pls(feTF_HF)); |
|
redet RE2 (.rst(Rst), .clk(Clk), .din(RF_HF), .pls(reRF_HF)); |
fedet FE2 (.rst(Rst), .clk(Clk), .din(RF_HF), .pls(feRF_HF)); |
redet RE3 (.rst(Rst), .clk(Clk), .din(RF_EF), .pls(reRF_EF)); |
|
redet RE4 (.rst(Rst), .clk(Clk), .din(RTO), .pls(reRTO)); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Transmit FIFO Empty Interrupt Flag |
// |
|
assign Rst_iTFE = Rst | (iTFE & Clr_Int & USR[0]); |
|
always @(posedge Clk or posedge reTF_EF) |
begin |
if(reTF_EF) |
iTFE <= #1 1; |
else if(Rst_iTFE) |
iTFE <= #1 reTF_EF; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Transmit FIFO Half Empty Interrupt Flag |
// |
|
assign Rst_iTHE = Rst | (iTHE & Clr_Int & USR[1]); |
|
always @(posedge Clk or posedge feTF_HF) |
begin |
if(feTF_HF) |
iTHE <= #1 1; |
else if(Rst_iTHE) |
iTHE <= #1 feTF_HF; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Receive Data Available Interrupt Flag |
// |
|
assign Rst_iRHF = Rst | (iRHF & (Clr_Int | feRF_HF | reRF_EF) & USR[2]); |
|
always @(posedge Clk or posedge reRF_HF) |
begin |
if(reRF_HF) |
iRHF <= #1 1; |
else if(Rst_iRHF) |
iRHF <= #1 reRF_HF; |
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Receive Timeout Interrupt Flag |
// |
|
assign Rst_iRTO = Rst | (iRTO & Clr_Int & USR[3]); |
|
always @(posedge Clk or posedge reRTO) |
begin |
if(reRTO) |
iRTO <= #1 1; |
else if(Rst_iRTO) |
iRTO <= #1 reRTO; |
end |
|
endmodule |
/trunk/RTL/UART_TXSM.v
0,0 → 1,314
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 21:22:38 05/10/2008 |
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/UART_TXSM.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This module implements the Transmit State Machine for the SSP |
// UART. |
// |
// The Baud Rate Generator implements the 16 baud rates defined |
// in Table 3 of the SSP UART Specification. |
// |
// Dependencies: None |
// |
// Revision History: |
// |
// 0.01 08E10 MAM File Created |
// |
// 1.00 08E24 MAM Modified and tested TxSM to allow for several addi- |
// tional conditions regarding Mode 1 - RS232 w/ Hand- |
// shaking. In particular, TxSM goes to pStart from |
// pShift if CTS is not asserted when the current word |
// has been shifted. |
// |
// 1.10 08E28 MAM Modified to remove I/O signals best processed above |
// this module: RTSi, RTSo, and DE. Removed from port |
// list and moved the decoded state ouput bits to the |
// end of the port list. Modified the TSRI and the TSR |
// length. TSRI now only processes the two MSBs of the |
// TSR load value. The length of TSR modified from 12 |
// to 10 bits because the logic 1 fill value and the |
// bit counter allow the stop bits to be implicit. The |
// result is a faster signal path. |
// |
// 1.20 08F08 MAM Modified TxSM to use a ROM to decode the [3:0]FMT |
// input like the RxSM. Changed the SR implementation |
// of the shift register into a registered multiplexer |
// implementation. Removed the bit counter and added |
// states to the SM to multiplex the data. Result is a |
// SM and SR that synthesizes to a speed that matches |
// the reported speed of the RxSM: 110+ MHz. This may |
// indicated that this UART may be useful as a high- |
// speed UART with an 8x over-sample instead of a 4x |
// oversample using a 48MHz clock input and a 2x DLL. |
// |
// 1.21 08F12 MAM Pulled Format Decoder ROM and moved to upper level |
// module. Added the outputs of the ROM to the port |
// list of the module. Module now supports more format |
// directly with the new direct inputs including com- |
// binations not normally used. The upper level module |
// must restrict the format inputs to those that are |
// proper. 7-bit formats require parity, and if not |
// set on input, then the parity generated will be |
// that specified by the Par bits. |
// |
// 2.00 11B06 MAM Converted to Verilog 2001. |
// |
// 2.01 13G06 MAM Corrected placement of #1 delay statements. Changed |
// combinatorial always to use @(*) instead of explicit |
// listing of signals in sensitivity list. |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module UART_TXSM( |
input Rst, |
input Clk, |
|
input CE_16x, // 16x Clock Enable - Baud Rate x16 |
|
input Len, // Word length: 0 - 8-bits; 1 - 7 bits |
input NumStop, // Number Stop Bits: 0 - 1 Stop; 1 - 2 Stop |
input ParEn, // Parity Enable |
input [1:0] Par, // 0 - Odd; 1 - Even; 2 - Space (0); 3 - Mark (1) |
|
input TF_EF, // Transmit THR Empty Flag |
|
input [7:0] THR, // Transmit Holding Register |
output reg TF_RE, // Transmit THR Read Enable Strobe |
|
input CTSi, // RS232 Mode CTS input |
|
output reg TxD, // Serial Data Out, LSB First, Start bit = 0 |
|
output TxIdle, // Transmit State Machine - Idle State |
output TxStart, // Transmit State Machine - Start State - CTS wait |
output TxShift, // Transmit State Machine - Shift State |
output TxStop // Transmit State Machine - Stop State - RTS clear |
); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Parameters |
// |
|
localparam pIdle = 0; // Idle - wait for data |
localparam pStopDelay = 1; // Stop - deassert DE/RTS after 1 bit delay |
localparam pStartDelay = 2; // Start - assert DE/RTS, delay 1 bit & CTSi |
localparam pUnused = 3; // Unused State |
localparam pStartBit = 10; // Shift - transmit Start Bit |
localparam pShift0 = 11; // Shift - transmit TSR contents (LSB) |
localparam pShift1 = 9; // Shift - transmit TSR contents |
localparam pShift2 = 8; // Shift - transmit TSR contents |
localparam pShift3 = 12; // Shift - transmit TSR contents |
localparam pShift4 = 13; // Shift - transmit TSR contents |
localparam pShift5 = 15; // Shift - transmit TSR contents |
localparam pShift6 = 14; // Shift - transmit TSR contents |
localparam pShift7 = 6; // Shift - transmit TSR contents (MSB) |
localparam pParityBit = 4; // Shift - transmit Parity Bit |
localparam pStopBit2 = 5; // Shift - transmit Stop Bit 1 |
localparam pStopBit1 = 7; // Shift - transmit Stop Bit 2 |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Local Signal Declarations |
// |
|
reg [3:0] Bit; // Bit Rate Divider |
reg CE_BCnt; // CEO Bit Rate Divider |
|
wire Odd, Evn; // Odd/Even parity signals |
reg ParBit; // Computed/assigned Parity Bit |
|
reg [8:0] TSR; // Transmit Shift Register |
|
(* FSM_ENCODING="SEQUENTIAL", |
SAFE_IMPLEMENTATION="YES", |
SAFE_RECOVERY_STATE="4'b0" *) |
reg [3:0] TxSM = pIdle; // Xmt State Machine |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
// Set Transmit Idle Status Bit |
|
assign TxIdle = (TxSM == pIdle); // Idle state |
assign TxStop = (TxSM == pStopDelay); // Wait 1 bit to release line |
assign TxStart = (TxSM == pStartDelay); // Take line and settle 1 bit |
assign TxShift = (TxSM[3] | TxSM[2]); // Xmt Shift States |
|
// Transmit State Machine Clock Enable |
|
assign CE_TxSM = (TxIdle ? CE_16x : CE_BCnt); |
|
// Shift Register Load Signal |
|
assign Ld_TSR = CE_TxSM & ~TF_EF & CTSi |
& ( (TxSM == pStartDelay) |
| (TxSM == pStopBit1) |
| (TxSM == pStopDelay) ); |
|
// Generate Transmit FIFO Read Enable |
|
always @(posedge Clk) |
begin |
if(TxIdle) |
TF_RE <= #1 1'b0; |
else |
TF_RE <= #1 Ld_TSR; |
end |
|
// Determine Load Value for Transmit Shift Register |
|
assign Evn = ((Len) ? ^{1'b0, THR[6:0]} : ^THR); |
assign Odd = ~Evn; |
|
always @(*) |
begin |
case(Par) |
2'b00 : ParBit <= Odd; // Odd |
2'b01 : ParBit <= Evn; // Even |
2'b10 : ParBit <= 0; // Space |
2'b11 : ParBit <= 1; // Mark |
endcase |
end |
|
// Transmit Shift Register |
|
always @(posedge Clk) |
begin |
if(TxIdle) |
TSR <= #1 9'b1_1111_1111; |
else if(Ld_TSR) |
TSR <= #1 {ParBit, THR[7:0]}; |
end |
|
always @(posedge Clk) |
begin |
if(Rst) |
#1 TxD <= 1; |
else case(TxSM) |
pStartBit : #1 TxD <= 0; |
pShift0 : #1 TxD <= TSR[0]; |
pShift1 : #1 TxD <= TSR[1]; |
pShift2 : #1 TxD <= TSR[2]; |
pShift3 : #1 TxD <= TSR[3]; |
pShift4 : #1 TxD <= TSR[4]; |
pShift5 : #1 TxD <= TSR[5]; |
pShift6 : #1 TxD <= TSR[6]; |
pShift7 : #1 TxD <= TSR[7]; |
pParityBit : #1 TxD <= TSR[8]; |
default : #1 TxD <= 1; |
endcase |
end |
|
// Bit Rate Divider |
|
always @(posedge Clk) |
begin |
if(TxIdle) |
Bit <= #1 4'b0; |
else if(CE_16x) |
Bit <= #1 Bit + 1; |
end |
|
always @(posedge Clk) |
begin |
if(TxIdle) |
CE_BCnt <= #1 0; |
else |
CE_BCnt <= #1 CE_16x & (Bit == 4'b1111); |
end |
|
// Transmit State Machine |
|
always @(posedge Clk) |
begin |
if(Rst) |
#1 TxSM <= pIdle; |
else if(CE_TxSM) |
case(TxSM) |
pIdle : TxSM <= #1 ((TF_EF) ? pIdle |
: pStartDelay); |
|
pStartDelay : TxSM <= #1 ((TF_EF) ? pIdle |
: ((CTSi) ? pStartBit |
: pStartDelay)); |
|
pStartBit : TxSM <= #1 pShift0; |
pShift0 : TxSM <= #1 pShift1; |
pShift1 : TxSM <= #1 pShift2; |
pShift2 : TxSM <= #1 pShift3; |
pShift3 : TxSM <= #1 pShift4; |
pShift4 : TxSM <= #1 pShift5; |
pShift5 : TxSM <= #1 pShift6; |
pShift6 : TxSM <= #1 ((Len) ? pParityBit |
: pShift7 ); |
pShift7 : TxSM <= #1 ((ParEn) ? pParityBit |
: ((NumStop) ? pStopBit2 |
: pStopBit1)); |
|
pParityBit : TxSM <= #1 ((NumStop) ? pStopBit2 |
: pStopBit1); |
|
pStopBit2 : TxSM <= #1 pStopBit1; |
pStopBit1 : TxSM <= #1 ((TF_EF) ? pStopDelay |
: pStartBit ); |
|
pStopDelay : TxSM <= #1 ((TF_EF) ? pIdle |
: ((CTSi) ? pStartBit |
: pStartDelay)); |
|
pUnused : TxSM <= #1 pIdle; |
endcase |
end |
|
endmodule |
/trunk/RTL/fedet.v
0,0 → 1,96
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
////////////////////////////////////////////////////////////////////////////////// |
// Company: Alpha Beta Technologies, Inc. |
// Engineer: Michael A. Morris |
// |
// Create Date: 03/01/2008 |
// Design Name: USB MBP HDL |
// Module Name: fedet.v |
// Project Name: 4020 HAWK ZAOM Upgrade |
// Target Devices: XC2S150-5PQ208I |
// Tool versions: ISE 8.2i |
// |
// Description: Multi-stage synchronizer with falling edge detection |
// |
// Dependencies: None |
// |
// Revision History: |
// |
// 0.01 08C01 MAM File Created |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module fedet(rst, clk, din, pls); |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Port Declarations |
// |
|
input rst; |
input clk; |
input din; |
output pls; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Module Level Declarations |
// |
|
reg [2:0] QSync; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Implementation |
// |
|
always @(posedge clk or posedge rst) begin |
if(rst) |
#1 QSync <= 3'b011; |
else |
#1 QSync <= {~QSync[0] & QSync[1], QSync[0], din}; |
end |
|
assign pls = QSync[2]; |
|
endmodule |
/trunk/RTL/DPSFmnRAM.coe
0,0 → 1,16
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
000 |
/trunk/Sim/tb_UART_TXSM.v
0,0 → 1,184
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 09:26:15 05/11/2008 |
// Design Name: LTAS |
// Module Name: C:/XProjects/ISE10.1i/LTAS/tb_UART_TxSM.v |
// Project Name: LTAS |
// Target Devices: XC3S700AN-5FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This test bench is intended to test the TxSM module for the SSP |
// UART. |
// |
// Verilog Test Fixture created by ISE for module: UART_TXSM |
// |
// Dependencies: UART_TxSM |
// |
// Revision History: |
// |
// 0.01 08E10 MAM File Created |
// |
// Additional Comments: |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
module tb_UART_TXSM_v; |
|
// Inputs |
reg Rst; |
reg Clk; |
reg CE_16x; |
reg [1:0] MD; |
|
reg [3:0] FMT; |
reg Len, NumStop, ParEn; |
reg [1:0] Par; |
|
reg [7:0] THR; |
reg TF_EF; |
reg RTSo; |
reg CTSi; |
|
// Outputs |
wire TF_RE; |
wire TxIdle; |
wire TxStart; |
wire TxShift; |
wire TxStop; |
wire TxD; |
wire DE; |
wire RTSi; |
|
// Instantiate the Unit Under Test (UUT) |
|
UART_TXSM uut ( |
.Rst(Rst), |
.Clk(Clk), |
.CE_16x(CE_16x), |
|
.Len(Len), |
.NumStop(NumStop), |
.ParEn(ParEn), |
.Par(Par), |
|
.TF_EF(TF_EF), |
.THR(THR), |
.TF_RE(TF_RE), |
.CTSi(CTSi), |
.TxD(TxD), |
|
.TxIdle(TxIdle), |
.TxStart(TxStart), |
.TxShift(TxShift), |
.TxStop(TxStop) |
); |
|
initial begin |
// Initialize Inputs |
Rst = 1; |
Clk = 0; |
CE_16x = 1; |
FMT = 0; |
THR = 8'h77; |
TF_EF = 1; |
RTSo = 1; |
CTSi = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
Rst = 0; |
|
// Add stimulus here |
|
// RS-232 w/ Handshaking |
|
@(posedge Clk) #1 TF_EF = 0; |
#100 CTSi = 1; // Wait before asserting input handshake signal |
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
#400 CTSi = 0; // Deassert input handshake signal |
|
@(negedge TxStop); |
THR = 8'h55; |
#400 CTSi = 1; |
TF_EF = 0; |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk); |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
#200 CTSi = 0; |
|
@(negedge TxStop); |
|
THR = 8'h5A; |
TF_EF = 0; |
|
@(posedge TxStart) CTSi = 1; |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
@(negedge TxStop); |
|
THR = 8'hA5; |
TF_EF = 0; |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
#100 CTSi = 0; |
|
@(posedge TxStop); |
|
THR = 8'h99; |
TF_EF = 0; |
|
@(posedge TxStart) |
#100 CTSi = 1; |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
@(posedge TxStop) |
CTSi = 0; |
|
end |
|
/////////////////////////////////////////////////////////////////////////////// |
|
// Clocks |
|
always #5 Clk = ~Clk; |
|
// Format Decode |
|
always @(FMT) |
case(FMT) |
4'b0000 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0001 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0010 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b00}; // 8O1 |
4'b0011 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b01}; // 8E1 |
4'b0100 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b10}; // 8S1 |
4'b0101 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b11}; // 8M1 |
4'b0110 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0111 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b0, 2'b00}; // 8N2 |
4'b1000 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b00}; // 8O2 |
4'b1001 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b01}; // 8E2 |
4'b1010 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b10}; // 8S2 |
4'b1011 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b11}; // 8M2 |
4'b1100 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b0, 1'b1, 2'b00}; // 7O1 |
4'b1101 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b0, 1'b1, 2'b01}; // 7E1 |
4'b1110 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b1, 1'b1, 2'b00}; // 7O2 |
4'b1111 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b1, 1'b1, 2'b01}; // 7E2 |
endcase |
|
endmodule |
|
/trunk/Sim/tb_DPSFmnCE.v
0,0 → 1,238
/////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2007-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
///////////////////////////////////////////////////////////////////////////////`timescale 1ns / 1ps |
|
`timescale 1ns / 1ps |
|
//////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 14:41:48 12/22/2007 |
// Design Name: DPSFnmCE |
// Module Name: tb_DPSFmnCE.v |
// Project Name: 4020 HAWK ZAOM Upgrade, 0420-HAWKIF |
// Target Device: XC2S150-5PQ208I |
// Tool versions: ISE 8.2i |
// |
// Description: Test bench for the Dual-Port Synchrnouse FIFO RAM. Default |
// parameters are used for the module instantiation. |
// |
// Verilog Test Fixture created by ISE for module: DPSFnmCE |
// |
// Dependencies: None |
// |
// Revision: |
// |
// 0.01 07L22 MAM File Created |
// |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module tb_DPSFmnCE_v; |
|
// Inputs |
reg Rst; |
reg Clk; |
reg WE; |
reg RE; |
reg [15:0] DI; |
|
// Outputs |
wire [15:0] DO; |
wire FF; |
wire EF; |
wire HF; |
wire [4:0] Cnt; |
|
// Instantiate the Unit Under Test (UUT) |
DPSFnmCE uut ( |
.Rst(Rst), |
.Clk(Clk), |
.WE(WE), |
.RE(RE), |
.DI(DI), |
.DO(DO), |
.FF(FF), |
.EF(EF), |
.HF(HF), |
.Cnt(Cnt) |
); |
|
initial begin |
// Initialize Inputs |
Rst = 1; |
Clk = 1; |
WE = 0; |
RE = 0; |
DI = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
|
Rst = 0; |
|
FIFO_Wr(16'h1111); |
FIFO_Wr(16'h2222); |
FIFO_Wr(16'h3333); |
FIFO_Wr(16'h4444); |
|
FIFO_Wr(16'h5555); |
FIFO_Wr(16'h6666); |
FIFO_Wr(16'h7777); |
FIFO_Wr(16'h8888); |
|
FIFO_Wr(16'h9999); |
FIFO_Wr(16'hAAAA); |
FIFO_Wr(16'hBBBB); |
FIFO_Wr(16'hCCCC); |
|
FIFO_Wr(16'hDDDD); |
FIFO_Wr(16'hEEEE); |
FIFO_Wr(16'hFFFF); |
FIFO_Wr(16'h0000); |
|
FIFO_Rd; |
|
FIFO_Wr(16'h0001); |
|
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
|
FIFO_Wr(16'h0001); |
FIFO_Wr(16'h0002); |
FIFO_Wr(16'h0004); |
FIFO_Wr(16'h0008); |
FIFO_Wr(16'h0010); |
FIFO_Wr(16'h0020); |
FIFO_Wr(16'h0040); |
FIFO_Wr(16'h0080); |
FIFO_Wr(16'h0100); |
FIFO_Wr(16'h0200); |
FIFO_Wr(16'h0400); |
FIFO_Wr(16'h0800); |
FIFO_Wr(16'h1000); |
FIFO_Wr(16'h2000); |
FIFO_Wr(16'h4000); |
FIFO_Wr(16'h8000); |
|
FIFO_Wr(16'h8001); |
|
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
|
FIFO_RW(16'h8001); |
|
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
FIFO_Rd; |
end |
|
always #5 Clk = ~Clk; |
|
// FIFO Write Task |
|
task FIFO_Wr; |
|
input [15:0] Data; |
|
begin |
@(posedge Clk); |
#1 WE = 1; DI = Data; |
@(posedge Clk); |
#1 WE = 0; |
end |
|
endtask |
|
// FIFO Read Task |
|
task FIFO_Rd; |
|
begin |
@(posedge Clk); |
#1 RE = 1; |
@(posedge Clk); |
#1 RE = 0; |
end |
|
endtask |
|
// FIFO Simultaneous Read/Write Task |
|
task FIFO_RW; |
|
input [15:0] Data; |
|
begin |
@(posedge Clk); |
#1 WE = 1; RE = 1; DI = Data; |
@(posedge Clk); |
#1 WE = 0; RE = 0; |
end |
|
endtask |
|
endmodule |
|
/trunk/Sim/tb_SSP_UART.v
0,0 → 1,152
/////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
///////////////////////////////////////////////////////////////////////////////`timescale 1ns / 1ps |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 18:21:47 06/13/2008 |
// Design Name: LTAS |
// Module Name: C:/XProjects/ISE10.1i/LTAS/tb_SSP_UART.v |
// Project Name: LTAS |
// Target Device: XC3S700AN-5FGG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: Test Fixture for full SSP UART |
// |
// Verilog Test Fixture created by ISE for module: SSP_UART |
// |
// Dependencies: SSP_UART |
// |
// Revision History: |
// |
// 0.01 08F13 MAM File Created |
// |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module tb_SSP_UART_v; |
|
// UUT Interface |
|
reg Rst; |
reg Clk; |
|
reg SSP_SSEL; |
reg SSP_SCK; |
reg [2:0] SSP_RA; |
reg SSP_WnR; |
reg SSP_EOC; |
reg [11:0] SSP_DI; |
wire [11:0] SSP_DO; |
|
wire TxD_232; |
reg RxD_232; |
wire xRTS; |
reg xCTS; |
|
wire TxD_485; |
reg RxD_485; |
wire xDE; |
|
wire IRQ; |
|
wire TxIdle; |
wire RxIdle; |
|
// Instantiate the Unit Under Test (UUT) |
|
SSP_UART uut ( |
.Rst(Rst), |
.Clk(Clk), |
|
.SSP_SSEL(SSP_SSEL), |
.SSP_SCK(SSP_SCK), |
.SSP_RA(SSP_RA), |
.SSP_WnR(SSP_WnR), |
.SSP_EOC(SSP_EOC), |
.SSP_DI(SSP_DI), |
.SSP_DO(SSP_DO), |
|
.TxD_232(TxD_232), |
.RxD_232(RxD_232), |
.xRTS(xRTS), |
.xCTS(xCTS), |
|
.TxD_485(TxD_485), |
.RxD_485(RxD_485), |
.xDE(xDE), |
|
.IRQ(IRQ), |
|
.TxIdle(TxIdle), |
.RxIdle(RxIdle) |
); |
|
initial begin |
// Initialize Inputs |
Rst = 1; |
Clk = 1; |
SSP_SSEL = 0; |
SSP_SCK = 1; |
SSP_RA = 0; |
SSP_WnR = 0; |
SSP_EOC = 0; |
SSP_DI = 0; |
RxD_232 = 1; |
xCTS = 0; |
RxD_485 = 1; |
|
// Wait 100 ns for global reset to finish |
#101 Rst = 0; |
|
// Add stimulus here |
|
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Simulation Clocks |
// |
|
always #5 Clk = ~Clk; |
|
endmodule |
|
/trunk/Sim/tb_UART_RXSM.v
0,0 → 1,210
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 18:00:24 06/07/2008 |
// Design Name: LTAS |
// Module Name: C:/XProjects/ISE10.1i/LTAS/tb_UART_RxSM.v |
// Project Name: LTAS |
// Target Devices: XC3S700AN-5FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This test bench is intended to test the RxSM module for the SSP |
// UART. |
// |
// Verilog Test Fixture created by ISE for module: UART_RXSM |
// |
// Dependencies: UART_TxSM, UART_RxSM |
// |
// Revision History: |
// |
// 0.01 08F07 MAM File Created |
// |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module tb_UART_RXSM_v; |
|
// Inputs |
reg Rst; |
reg Clk; |
reg CE_16x; |
reg XLen, XNumStop, XParEn; |
reg RLen, RNumStop, RParEn; |
reg [1:0] XPar, RPar; |
reg [3:0] RFMT, XFMT; |
wire RxD; |
|
// Outputs |
wire [8:0] RD; |
wire WE_RHR; |
wire RxWait; |
wire RxIdle; |
wire RxStart; |
wire RxShift; |
wire RxParity; |
wire RxStop; |
wire RxError; |
|
reg TF_EF; |
reg [7:0] THR; |
wire TF_RE; |
wire TxIdle, TxStart, TxShift, TxStop; |
|
// Instantiate the UART TxSM Module (U1) to drive the RxD Input |
|
UART_TXSM U1 ( |
.Rst(Rst), |
.Clk(Clk), |
.CE_16x(CE_16x), |
.Len(XLen), |
.NumStop(XNumStop), |
.ParEn(XParEn), |
.Par(XPar), |
.TF_EF(TF_EF), |
.THR(THR), |
.TF_RE(TF_RE), |
.CTSi(1'b1), |
.TxD(RxD), |
.TxIdle(TxIdle), |
.TxStart(TxStart), |
.TxShift(TxShift), |
.TxStop(TxStop) |
); |
|
// Instantiate the Unit Under Test (UUT) |
|
UART_RXSM uut ( |
.Rst(Rst), |
.Clk(Clk), |
.CE_16x(CE_16x), |
.Len(RLen), |
.NumStop(RNumStop), |
.ParEn(RParEn), |
.Par(RPar), |
.RxD(RxD), |
.RD(RD), |
.WE_RHR(WE_RHR), |
.RxWait(RxWait), |
.RxIdle(RxIdle), |
.RxStart(RxStart), |
.RxShift(RxShift), |
.RxParity(RxParity), |
.RxStop(RxStop), |
.RxError(RxError) |
); |
|
initial begin |
Rst = 1; |
Clk = 0; |
CE_16x = 1; |
RFMT = 0; // 8N1 - default |
XFMT = 0; |
THR = 8'h77; |
TF_EF = 1; |
|
// Wait 100 ns for global reset to finish |
|
#101 Rst = 0; |
|
// Add stimulus here |
|
@(posedge Clk) #1 TF_EF = 0; |
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
@(posedge TxIdle); |
THR = 8'h55; |
TF_EF = 0; |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk); |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
@(negedge TxStop); |
|
TF_EF = 0; |
THR = 8'h5A; |
RFMT = 4'b1100; // 7O1 |
XFMT = RFMT; |
@(posedge TxStart); |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
@(negedge TxStop); |
|
TF_EF = 0; |
THR = 8'h5A; |
RFMT = 4'b1100; // 7O1 |
XFMT = 4'b1101; // 7E1 |
@(posedge TxStart); |
|
@(posedge TF_RE); // Emulate read of External Tx FIFO |
@(posedge Clk) #1 TF_EF = 1; |
|
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Clocks |
// |
|
always #5 Clk = ~Clk; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Simulation Drivers/Models |
// |
|
// Transmit Format Decode |
|
always @(XFMT) |
case(XFMT) |
4'b0000 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0001 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0010 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b1, 2'b00}; // 8O1 |
4'b0011 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b1, 2'b01}; // 8E1 |
4'b0100 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b1, 2'b10}; // 8S1 |
4'b0101 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b1, 2'b11}; // 8M1 |
4'b0110 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0111 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b1, 1'b0, 2'b00}; // 8N2 |
4'b1000 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b1, 1'b1, 2'b00}; // 8O2 |
4'b1001 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b1, 1'b1, 2'b01}; // 8E2 |
4'b1010 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b1, 1'b1, 2'b10}; // 8S2 |
4'b1011 : {XLen, XNumStop, XParEn, XPar} <= {1'b0, 1'b1, 1'b1, 2'b11}; // 8M2 |
4'b1100 : {XLen, XNumStop, XParEn, XPar} <= {1'b1, 1'b0, 1'b1, 2'b00}; // 7O1 |
4'b1101 : {XLen, XNumStop, XParEn, XPar} <= {1'b1, 1'b0, 1'b1, 2'b01}; // 7E1 |
4'b1110 : {XLen, XNumStop, XParEn, XPar} <= {1'b1, 1'b1, 1'b1, 2'b00}; // 7O2 |
4'b1111 : {XLen, XNumStop, XParEn, XPar} <= {1'b1, 1'b1, 1'b1, 2'b01}; // 7E2 |
endcase |
|
// Format Decode |
|
always @(RFMT) |
case(RFMT) |
4'b0000 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0001 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0010 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b1, 2'b00}; // 8O1 |
4'b0011 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b1, 2'b01}; // 8E1 |
4'b0100 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b1, 2'b10}; // 8S1 |
4'b0101 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b1, 2'b11}; // 8M1 |
4'b0110 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b0, 1'b0, 2'b00}; // 8N1 |
4'b0111 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b1, 1'b0, 2'b00}; // 8N2 |
4'b1000 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b1, 1'b1, 2'b00}; // 8O2 |
4'b1001 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b1, 1'b1, 2'b01}; // 8E2 |
4'b1010 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b1, 1'b1, 2'b10}; // 8S2 |
4'b1011 : {RLen, RNumStop, RParEn, RPar} <= {1'b0, 1'b1, 1'b1, 2'b11}; // 8M2 |
4'b1100 : {RLen, RNumStop, RParEn, RPar} <= {1'b1, 1'b0, 1'b1, 2'b00}; // 7O1 |
4'b1101 : {RLen, RNumStop, RParEn, RPar} <= {1'b1, 1'b0, 1'b1, 2'b01}; // 7E1 |
4'b1110 : {RLen, RNumStop, RParEn, RPar} <= {1'b1, 1'b1, 1'b1, 2'b00}; // 7O2 |
4'b1111 : {RLen, RNumStop, RParEn, RPar} <= {1'b1, 1'b1, 1'b1, 2'b01}; // 7E2 |
endcase |
|
endmodule |
|
/trunk/Sim/tb_UART_BRG.v
0,0 → 1,174
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates |
// |
// All rights reserved. The source code contained herein is publicly released |
// under the terms and conditions of the GNU Lesser Public License. No part of |
// this source code may be reproduced or transmitted in any form or by any |
// means, electronic or mechanical, including photocopying, recording, or any |
// information storage and retrieval system in violation of the license under |
// which the source code is released. |
// |
// The source code contained herein is free; it may be redistributed and/or |
// modified in accordance with the terms of the GNU Lesser General Public |
// License as published by the Free Software Foundation; either version 2.1 of |
// the GNU Lesser General Public License, or any later version. |
// |
// The source code contained herein is freely released WITHOUT ANY WARRANTY; |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for |
// more details.) |
// |
// A copy of the GNU Lesser General Public License should have been received |
// along with the source code contained herein; if not, a copy can be obtained |
// by writing to: |
// |
// Free Software Foundation, Inc. |
// 51 Franklin Street, Fifth Floor |
// Boston, MA 02110-1301 USA |
// |
// Further, no use of this source code is permitted in any form or means |
// without inclusion of this banner prominently in any derived works. |
// |
// Michael A. Morris |
// Huntsville, AL |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
/////////////////////////////////////////////////////////////////////////////// |
// Company: M. A. Morris & Associates |
// Engineer: Michael A. Morris |
// |
// Create Date: 19:16:35 05/10/2008 |
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART |
// Module Name: ../VerilogCoponentsLib/SSP_UART/tb_UART_BRG.v |
// Project Name: Verilog Components Library |
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I |
// Tool versions: ISE 10.1i SP3 |
// |
// Description: This test bench is intended to test the BRG module for the SSP |
// UART. |
// |
// Verilog Test Fixture created by ISE for module: UART_BRG |
// |
// Dependencies: |
// |
// Revision History: |
// |
// 0.01 08E10 MAM File Created |
// |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module tb_UART_BRG_v; |
|
// Inputs |
reg Rst; |
reg Clk; |
reg [3:0] PS; |
reg [7:0] Div; |
|
reg [3:0] Baud; |
|
// Outputs |
wire CE_16x; |
|
// Instantiate the Unit Under Test (UUT) |
|
UART_BRG uut ( |
.Rst(Rst), |
.Clk(Clk), |
|
.PS(PS), |
.Div(Div), |
|
.CE_16x(CE_16x) |
); |
|
initial begin |
// Initialize Inputs |
Rst = 1; |
Clk = 0; |
Baud = 0; |
|
// Wait 100 ns for global reset to finish |
#101; |
|
Rst = 0; |
|
// Add stimulus here |
|
|
@(posedge Clk); |
@(posedge Clk); |
@(posedge Clk); |
@(posedge Clk); |
@(posedge Clk); |
@(posedge Clk); |
@(posedge Clk); |
@(posedge Clk); |
|
@(posedge Clk) #1 Baud = 1; |
@(negedge CE_16x) #1 Baud = 2; |
@(negedge CE_16x) #1 Baud = 3; |
@(negedge CE_16x); |
|
@(negedge CE_16x) #1 Baud = 4; |
@(negedge CE_16x) #1 Baud = 5; |
@(negedge CE_16x) #1 Baud = 6; |
@(negedge CE_16x) #1 Baud = 7; |
@(negedge CE_16x) #1 Baud = 8; |
@(negedge CE_16x) #1 Baud = 9; |
@(negedge CE_16x) #1 Baud = 10; |
@(negedge CE_16x) #1 Baud = 11; |
@(negedge CE_16x) #1 Baud = 12; |
@(negedge CE_16x) #1 Baud = 13; |
@(negedge CE_16x) #1 Baud = 14; |
@(negedge CE_16x) #1 Baud = 15; |
@(negedge CE_16x) |
|
@(negedge CE_16x) Baud = 0; |
|
end |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Clocks |
// |
|
always #10.416 Clk = ~Clk; |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// Simulation Drivers/Models |
// |
|
// Baud Rate Generator's PS and Div for defined Baud Rates (48 MHz Oscillator) |
|
always @(Baud) |
begin |
case(Baud) |
4'b0000 : {Div, PS} <= 12'b0000_0000_0000; // Div = 1; PS = 1 |
4'b0001 : {Div, PS} <= 12'b0000_0001_0000; // Div = 2; PS = 1 |
4'b0010 : {Div, PS} <= 12'b0000_0101_0000; // Div = 6; PS = 1 |
4'b0011 : {Div, PS} <= 12'b0000_1111_0000; // Div = 16; PS = 1 |
4'b0100 : {Div, PS} <= 12'b0000_0000_1100; // Div = 1; PS = 13 |
4'b0101 : {Div, PS} <= 12'b0000_0001_1100; // Div = 2; PS = 13 |
4'b0110 : {Div, PS} <= 12'b0000_0010_1100; // Div = 3; PS = 13 |
4'b0111 : {Div, PS} <= 12'b0000_0011_1100; // Div = 4; PS = 13 |
4'b1000 : {Div, PS} <= 12'b0000_0101_1100; // Div = 6; PS = 13 |
4'b1001 : {Div, PS} <= 12'b0000_1011_1100; // Div = 12; PS = 13 |
4'b1010 : {Div, PS} <= 12'b0001_0111_1100; // Div = 24; PS = 13 |
4'b1011 : {Div, PS} <= 12'b0010_1111_1100; // Div = 48; PS = 13 |
4'b1100 : {Div, PS} <= 12'b0101_1111_1100; // Div = 96; PS = 13 |
4'b1101 : {Div, PS} <= 12'b1011_1111_1100; // Div = 192; PS = 13 |
4'b1110 : {Div, PS} <= 12'b0111_1111_1100; // Div = 128; PS = 13 |
4'b1111 : {Div, PS} <= 12'b1111_1111_1100; // Div = 256; PS = 13 |
endcase |
end |
|
endmodule |
|