📄 uartctrl.tdf
字号:
TITLE "UART Controller";
%//////////////////
// INCLUDE FILES //
//////////////////%
INCLUDE "lpm_dff.inc";
INCLUDE "lpm_mux.inc";
INCLUDE "lpm_bustri.inc";
%////////////////////////////
// USER-DEFINED PARAMETERS //
////////////////////////////%
PARAMETERS
(
FCLK, -- Master Clock Frequency
CONFIG, -- configration register content
BAUDRATE -- Baudrate register content
);
%/////////////////////////
// CONSTANT DEFINITIONS //
/////////////////////////%
% DIVISOR VALUES %
CONSTANT DIV1200 = (FCLK+1200) DIV (2*1200) - 1; -- 1200 Baud
CONSTANT DIV2400 = (FCLK+2400) DIV (2*2400) - 1; -- 2400 Baud
CONSTANT DIV4800 = (FCLK+4800) DIV (2*4800) - 1; -- 4800 Baud
CONSTANT DIV9600 = (FCLK+9600) DIV (2*9600) - 1; -- 9600 Baud
CONSTANT DIV14400 = (FCLK+14400) DIV (2*14400) - 1; -- 14400 Baud
CONSTANT DIV19200 = (FCLK+19200) DIV (2*19200) - 1; -- 19200 Baud
CONSTANT DIV28800 = (FCLK+28800) DIV (2*28800) - 1; -- 28800 Baud
CONSTANT DIV38400 = (FCLK+38400) DIV (2*38400) - 1; -- 38400 Baud
CONSTANT DIV57600 = (FCLK+57600) DIV (2*57600) - 1; -- 57600 Baud
CONSTANT DIV115200 = (FCLK+115200) DIV (2*115200) - 1; -- 115200 Baud
%/////////////////////
// INPUTS & OUTPUTS //
/////////////////////%
SUBDESIGN UARTCTRL
(
Di[7..0] : INPUT; -- Input Data Bus
Do[7..0] : OUTPUT; -- Multiplexed Output Data Bus
CLK, RESET, RD, WR, CS, A[1..0] : INPUT; -- CPU Interface
INT, RCVD, SENT : OUTPUT;
-- D[7..0] : BIDIR;
TxDIVISOR[16..0], TxCfgReg[6..0], TxReg[7..0] : OUTPUT; -- Tx Interface
TxSTATUS, TxEnd : INPUT; -- CTSf, DSRf : INPUT;
TxStart, TxReset, TxCLK : OUTPUT;
RxSTATUS[4..0], RxReg[7..0] : INPUT; -- Rx Interface
RxDIVISOR[16..0], RxCfgReg[6..0] : OUTPUT;
RxEnd : INPUT; -- /RxRTS, /RxDTR : INPUT;
RxStart, RxReset, RxCLK : OUTPUT; -- , /RTS, /DTR : OUTPUT;
)
%//////////////////////////
// VARIABLE DECLARATIONS //
//////////////////////////%
VARIABLE
% INTERNAL VARIABLES %
--CfgReg[6..0] : NODE; -- UART Configuration Register
--BaudReg[7..0] : NODE; -- UART Baud Rate Register (Write Only)
DIVISOR[16..0] : NODE; -- Baud-Rate Clock Divisor
DOMUX[7..0] : NODE; -- Output Data Bus Multiplexer
DMXDo[3..0][7..0] : NODE; -- Demultiplexed Output Data Bus
DIVd[16..0] : NODE; -- D-inputs to Divisor Register
HANDSHAKE : NODE; -- Handshaking Type
BaudReg[7..0] : NODE;
CfgReg[7..0] : NODE;
% STATE MACHINES %
RxRdss : MACHINE WITH STATES (RxRd0, RxRd1, RxRd2); -- Status Register Read
TxWrss : MACHINE WITH STATES (TxWr0, TxWr1, TxWr2); -- Tx Register Write
%//////////////////
// LOGIC SECTION //
//////////////////%
BEGIN
% DEFAULT VALUES %
CfgReg[7..0] = CONFIG;
BaudReg[7..0] = BAUDRATE;
IF (BaudReg[] == 0) THEN DIVd[]=DIV1200; --Ratess=Rate3; -- Baud Rate = 1200
ELSIF (BaudReg[] == 1) THEN DIVd[]=DIV2400; --Ratess=Rate3; -- Baud Rate = 2400
ELSIF (BaudReg[] == 2) THEN DIVd[]=DIV4800; --Ratess=Rate3; -- Baud Rate = 4800
ELSIF (BaudReg[] == 3) THEN DIVd[]=DIV9600; --Ratess=Rate3; -- Baud Rate = 9600
ELSIF (BaudReg[] == 4) THEN DIVd[]=DIV14400; --Ratess=Rate3; -- Baud Rate = 14400
ELSIF (BaudReg[] == 5) THEN DIVd[]=DIV19200; --Ratess=Rate3; -- Baud Rate = 19200
ELSIF (BaudReg[] == 6) THEN DIVd[]=DIV28800; --Ratess=Rate3; -- Baud Rate = 28800
ELSIF (BaudReg[] == 7) THEN DIVd[]=DIV38400; --Ratess=Rate3; -- Baud Rate = 38400
ELSIF (BaudReg[] == 8) THEN DIVd[]=DIV57600; --Ratess=Rate3; -- Baud Rate = 57600
ELSIF (BaudReg[] == 9) THEN DIVd[]=DIV115200; --Ratess=Rate3; -- Baud Rate = 115200
ELSE DIVd[16..7]=0; DIVd[6..0]=BaudReg[6..0]; --Ratess=Rate3; -- Baud Rate = FCLK/(2*BaudReg[6..0] + 2)
END IF;
TxREG[] = LPM_DFF (Di[7..0], WR # CS # A1 # A0, VCC,,,,,, RESET,,) -- Tx Data Register
WITH (LPM_WIDTH=8)
RETURNS (.q[]);
DIVISOR[] = DIVd[];
DOMUX[] = LPM_MUX (.Data[][] = DMXDo[3..0][7..0], .Sel[] = A[1..0]) -- Output Data Bus Multiplexer
WITH (LPM_WIDTH=8, LPM_SIZE=4, LPM_WIDTHS=2)
RETURNS (.result[]);
RCVD = LPM_DFF (RxEND, CLK,,,,,,, RESET,,) -- Rx Interrupt
WITH (LPM_WIDTH=1)
RETURNS (.q[]);
SENT = LPM_DFF (TxEND, CLK,,,,,,, RESET,,) -- Tx Interrupt
WITH (LPM_WIDTH=1)
RETURNS (.q[]);
INT = LPM_DFF (RxEND # TxEND, CLK,,,,,,, RESET,,) -- Rx/Tx Common Interrupt
WITH (LPM_WIDTH=1)
RETURNS (.q[]);
% COMBINATORIAL LOGIC %
RxDIVISOR[]=DIVISOR[]; -- Common Rx/Tx Inputs
TxDIVISOR[]=DIVISOR[];
RxCfgReg[]=CfgReg[6..0];
TxCfgReg[]=CfgReg[6..0];
RxCLK=CLK;
TxCLK=CLK;
HANDSHAKE=CfgReg[6];
Do[]=DOMUX[]; -- Multiplexed Output Data Bus
DMXDo[0][]=RxREG[]; -- Demultiplexed Output Data Bus
DMXDo[1][0]=TxSTATUS;
DMXDo[1][5..1]=RxSTATUS[];
DMXDo[1][7..6]=0;
DMXDo[2][]=0;
DMXDo[3][0]=GND;--CTSf;
DMXDo[3][1]=GND;--DSRf;
DMXDo[3][7..2]=0;
RxReset=RESET; -- Rx Reset
TxReset=RESET; -- Tx Reset
% STATE MACHINES %
RxRdss.CLK = CLK;
RxRdss.RESET= RESET;
TxWrss.CLK = CLK;
TxWrss.RESET= RESET;
% Rx DATA REGISTER READ STATE MACHINE %
CASE RxRdss IS
WHEN RxRd0 => -- Wait for a Read from the Rx Data Register
IF !(CS # A0 # A1 # Rd # !WR) THEN RxRdss=RxRd1;
ELSE RxRdss=RxRd0;
END IF;
WHEN RxRd1 => -- Wait until Rx Data Register Read is completed
IF (CS # A0 # A1 # Rd # !WR) THEN RxRdss=RxRd2;
ELSE RxRdss=RxRd1;
END IF;
WHEN RxRd2 => -- Clear Rx Status Register
RxStart=VCC;
RxRdss=RxRd0;
END CASE;
% Tx DATA REGISTER WRITE STATE MACHINE %
CASE TxWrss IS
WHEN TxWr0 => -- Wait for a Write to the Tx Data Register
IF !(CS # A0 # A1 # !Rd # WR) THEN TxWrss=TxWr1;
ELSE TxWrss=TxWr0;
END IF;
WHEN TxWr1 => -- Wait until Tx Data Register Write is completed
IF (CS # A0 # A1 # !Rd # WR) THEN TxWrss=TxWr2;
ELSE TxWrss=TxWr1;
END IF;
WHEN TxWr2 => -- Enable Tx
TxStart=VCC;
TxWrss=TxWr0;
END CASE;
END;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -