TITLE "Serial signal generator / error counter rev.2.02 Jul. 12, 2012";
% Copyright (c) 2006-2012 Finetune co., ltd. and Takayuki HOSODA. %
% All rights reserved. %
% Bug reports should be sent to lyuka@finetune.co.jp %
%Switches%
%----------------------------------------------------------------%
%SW-push : ON : alternate display / increase bit rate%
%%
%DIPSW-1 : TEST -- ON: Syncronous, OFF: Asyncronous(RS232C)%
%DIPSW-2 : NONE -- ON: No parity(RS232C)%
%DIPSW-3 : ODD -- ON: Odd parity(RS232C)%
%DIPSW-4 : TXNEG -- ON: Logically invert the output(TxD) signal%
%DIPSW-5 : RXNEG -- ON: Logically invert the input (RxD) signal%
%DIPSW-6 : CRLF -- ON: LT = CRLF, OFF: LT = LF%
%DIPSW-7 : HFC -- ON: Enable hardware flow controll (i.e. CTS)%
%%
%SW-toggle : TXON -- 0N: Activate transmit signal%
%%
%Mnemonic - logic expression : comment%
%--------------------------------------------------------------------------%
%7 E - !test & !none & !odd : RS232C 7bit evan parity 0x20-0xfe, LT%
%7 O - !test & !none & odd : RS232C 7bit odd parity 0x20-0xfe, LT%
%8 n - !test & none & !odd : RS232C 8bit no parity 0x20-0xfe, LT%
%F F - !test & one & odd : RS232C 8bit no parity 0x00-0xff%
%n 9 - test & !none & !odd : 9 stage PN, ITU-T Rec. O.150, O.153%
%1 5 - test & !none & odd : 15 stage PN, ITU-T Rec. O.150, O.151%
%2 3 - test & none & !odd : 23 stage PN, ITU-T Rec. O.150, O.151%
%u n - test & none & odd : Alternate (square wave)%
%%
%Decimal points indicator (while TXON)%
%-------------------------------------------------------%
%DP3 , DP2 , DP1 , DP0%
%L->H, L->H, L->X, L->X%
%H->H, H->X, H->L, H->L%
%lit lit off off : stack to high%
%off lit lit off : inverted%
%off off lit lit : stack to low%
%lit lit lit lit : random error%
%-------------------------------------------------------%
%%
%Decimal points indicator (while diplaying the format)%
%-------------------------------------------------------%
%--- --- lit --- : CR+LF%
%--- --- --- lit : HHC enabled%
%%
%Indicators%
%-------------------------------------------------------%
%TXON : lit : TXON%
%CTS : lit : clear to send%
%%
%Display and its code%
%-------------------------------------------------------%
%-- code : 0 1 2 3 4 5 6 7 8 9 a b c d e f%
%-- display: 0 1 2 3 4 5 6 7 8 9 E F u n - (blank)%
%%
%Frequencies%
%-------------------------------------------------------%
%fclk = 14.7456MHz%
%fdiv0 : 7.3728MHz 0%
%fdiv1 : 3.6864MHz 1%
%fdiv2 : 1.8432MHz 2%
%fdiv3 : 921.6kHz 3%
%fdiv4 : 460.8kHz 4%
%fdiv5 : 230.4kHz 5%
%fdiv6 : 115.2kHz 6%
%fdiv7 : 57.6kHz 7%
%fdiv8 : 28.8kHz%
%fdiv9 : 14.4kHz 10%
%bdiv2 : 38.4kHz 8%
%bdiv3 : 19.2kHz 9%
%bdiv4 : 9.6kHz 11%
%bdiv5 : 4.8kHz 12 , for 7-segment LED dynamic scan%
%bdiv6 : 2.4kHz 13 , for 7-segment LED dynamic scan%
%bdiv7 : 1.2kHz 14%
%bdiv8 : 600Hz 15 / 1.67ms%
%bdiv9 : 300Hz / 3.33ms%
%bdiv10: 150Hz / 6.67ms%
%bdiv11: 75Hz / 13.33ms , for key scan (kstb)%
%ccnt0 : / 26.67ms%
%ccnt1 : / 53.33ms%
%ccnt2 : /106.67ms%
%ccnt3 : /213.33ms%
%ccnt4 : /426.66ms, for key hold%
%ccnt5 : >426.66ms, for key hold%
SUBDESIGN test232c
(
fclk : INPUT; -- gclk1 14.7456MHz
_sw : INPUT; -- push switch to change bit rate
_test : INPUT; -- 0: select PN9, 1: RS232C
_none : INPUT; -- 0: 8bit without parity, 1: 7bit with parity
_odd : INPUT; -- 0: odd parity, 1: even parity
_txinv : INPUT; -- 0: active=low, 1: active=high
_rxinv : INPUT; -- 0: active=low, 1: active=high
_crlf : INPUT; -- 0: LF, 1:CRLF
_hfc : INPUT; -- 0: enable hardware flow control
_txon : INPUT; -- Tx ON
_rxd : INPUT; -- RxD,
_cts : INPUT; -- CTS, 0: clear to send
ctsd : OUTPUT; -- clear to send indicator
txonb : OUTPUT; -- Tx ON indicator
led[7..0] : OUTPUT; -- baud rate indicator
_ledd[3..0] : OUTPUT; -- led digit driver
bclk : OUTPUT; -- baud rate clock
rerr : OUTPUT; -- receive data error
txdb : OUTPUT; -- serial data to the line driver
sync : OUTPUT; -- start bit
)
VARIABLE
fdiv[9..0] : DFF;
frc : NODE;
tdiv[1..0] : DFFE;
trc : NODE;
bdiv[11..0] : DFFE;
bclk : DFF;
mclk : DFF;
mclkd : DFF;
mstb : NODE;
kclk : DFF;
kstb : NODE;
ccnt[5..0] : DFFE;
lerr : JKFFE;
lerrd : DFFE;
herr : JKFFE;
herrd : DFFE;
lfsr[22..0] : DFFE;
digd[3..0] : NODE;
digc[3..0] : NODE;
digb[3..0] : NODE;
diga[3..0] : NODE;
ledi[3..0] : NODE;
ledd[3..0] : NODE;
_ledd[3..0] : OPNDRN;
rerr : DFFE;
errd[3..0] : DFFE;
errc[3..0] : DFFE;
errb[3..0] : DFFE;
erra[3..0] : DFFE;
clrerr : DFF;
overflow : NODE;
ctsb : DFFE;
ctsd : JKFFE;
sw[2..0] : DFFE;
swd : JKFFE;
swdd : DFFE;
swtx[2..0] : DFFE;
txon : JKFFE;
selsw[3..0] : DFFE;
select[3..0] : DFFE;
stopbit : NODE;
sync : DFFE;
ld : NODE;
txdata[7..0] : DFFE;
txd : DFFE;
test : DFFE;
parity : NODE;
none : DFFE;
odd : DFFE;
txinv : DFFE;
rxinv : DFFE;
crlf : DFFE;
hfc : DFFE;
mode_c8n : NODE;
mode_cff : NODE;
mode_c7e : NODE;
mode_c7o : NODE;
mode_n9 : NODE;
mode_n15 : NODE;
mode_n23 : NODE;
mode_pb : NODE;
mode[7..0] : NODE;
disp_bps : NODE;
disp_err : NODE;
disp_info : NODE;
tstate : MACHINE OF BITS (txcount[3..0])
WITH STATES (stop = 0,
start = 1,
bit0 = 2,
bit1 = 3,
bit2 = 4,
bit3 = 5,
bit4 = 6,
bit5 = 7,
bit6 = 8,
bit7 = 9);
BEGIN
fdiv[9..0].clk = GLOBAL(fclk);
fdiv[9..0] = fdiv[9..0] + 1;
frc = (fdiv[3..0] == h"f");
tdiv[1..0].clk = GLOBAL(fclk);
tdiv[1..0].ena = frc;
tdiv1 = tdiv0;
tdiv0 = !tdiv1 # !tdiv0;
trc = ((tdiv[1..0] == 3) & frc);
bdiv[11..0].clk = GLOBAL(fclk);
bdiv[11..0].ena = trc;
bdiv[11..0] = (bdiv[11..0] + 1);
kclk.clk = GLOBAL(fclk);
kclk = bdiv11;
kstb = (bdiv11 & !kclk); -- 13.3ms interval
sw[2..0].clk = GLOBAL(fclk);
sw[2..0].ena = kstb;
--sw[2..0] = (!txon & sw[1..0], !_sw) & kstb;
sw[2..0] = (sw[1..0], !_sw) & kstb;
swd.clk = GLOBAL(fclk);
swd.ena = GLOBAL(mstb);
swd.j = (sw[2..0] == b"111"); -- 40ms period
swd.k = (sw[2..0] == b"000");
swdd.clk = GLOBAL(fclk);
swdd = swd;
ccnt[5..0].clk = GLOBAL(fclk);
ccnt[5..0].ena = kstb;
ccnt[5..0] = (ccnt[5..0] + 1) & swd & !ccnt5
# (ccnt[5..0] ) & swd & ccnt5;
selsw[3..0].clk = GLOBAL(fclk);
selsw[3..0].ena = !swd & swdd & !ccnt5;
selsw[3..0] = (selsw[3..0] + 1);
select[3..0].clk = GLOBAL(fclk);
select[3..0].ena = stopbit & mstb;
select[3..0] = selsw[3..0];
swtx[2..0].clk = GLOBAL(fclk);
swtx[2..0].ena = kstb;
swtx[2..0] = (swtx[1..0], !_txon);
txon.clk = GLOBAL(fclk);
txon.ena = GLOBAL(mstb);
txon.j = (swtx[2..0] == b"111"); -- 40ms period
txon.k = (swtx[2..0] == b"000");
txonb = txon;
(ctsb, ctsd, hfc).clk = GLOBAL(fclk);
(ctsb, ctsd, hfc).ena = GLOBAL(mstb);
hfc = !_hfc;
ctsb = (!_cts $ rxinv) # (!hfc);
ctsd.j = ctsb;
ctsd.k = !ctsb & kstb;
(none, odd, txinv, rxinv, test, crlf).clk = GLOBAL(fclk);
(none, odd, txinv, rxinv, test, crlf).ena = (stopbit & mstb & !test)
# ( kstb & test);
test = !_test;
none = !_none;
odd = !_odd;
txinv = !_txinv;
rxinv = !_rxinv;
crlf = !_crlf;
disp_bps = (!sw0 & !txon )
#( sw0 & !ccnt5 );
disp_info = ( sw0 & ccnt5 );
disp_err = (!sw0 & txon);
mode_c7e = ( !test & !none & !odd );
mode_c7o = ( !test & !none & odd );
mode_c8n = ( !test & none & !odd );
mode_cff = ( !test & none & odd );
mode_n9 = ( test & !none & !odd );
mode_n15 = ( test & !none & odd );
mode_n23 = ( test & none & !odd );
mode_pb = ( test & none & odd );
mode[7..0] = ( h"7a" & mode_c7e
# h"70" & mode_c7o
# h"8d" & mode_c8n
# h"bb" & mode_cff
# h"d9" & mode_n9
# h"15" & mode_n15
# h"23" & mode_n23
# h"cd" & mode_pb );
digd[3..0] = ((h"7" & (select[3..0] == 15))
#(h"3" & (select[3..0] == 14))
#(h"1" & (select[3..0] == 13))
#(h"9" & (select[3..0] == 12))
#(h"4" & (select[3..0] == 11))
#(h"2" & (select[3..0] == 10))
#(h"1" & (select[3..0] == 9))
#(h"f" & (select[3..0] == 8))
#(h"f" & (select[3..0] == 7))
#(h"f" & (select[3..0] == 6))
#(h"f" & (select[3..0] == 5))
#(h"9" & (select[3..0] == 4))
#(h"4" & (select[3..0] == 3))
#(h"2" & (select[3..0] == 2))
#(h"1" & (select[3..0] == 1))
#(h"f" & (select[3..0] == 0)));
digc[3..0] = ((h"3" & (select[3..0] == 15))
#(h"6" & (select[3..0] == 14))
#(h"8" & (select[3..0] == 13))
#(h"2" & (select[3..0] == 12))
#(h"6" & (select[3..0] == 11))
#(h"3" & (select[3..0] == 10))
#(h"1" & (select[3..0] == 9))
#(h"5" & (select[3..0] == 8))
#(h"3" & (select[3..0] == 7))
#(h"1" & (select[3..0] == 6))
#(h"1" & (select[3..0] == 5))
#(h"6" & (select[3..0] == 4))
#(h"8" & (select[3..0] == 3))
#(h"4" & (select[3..0] == 2))
#(h"2" & (select[3..0] == 1))
#(h"6" & (select[3..0] == 0)));
digb[3..0] = ((h"7" & (select[3..0] == 15))
#(h"8" & (select[3..0] == 14))
#(h"4" & (select[3..0] == 13))
#(h"1" & (select[3..0] == 12))
#(h"0" & (select[3..0] == 11))
#(h"0" & (select[3..0] == 10))
#(h"5" & (select[3..0] == 9))
#(h"7" & (select[3..0] == 8))
#(h"8" & (select[3..0] == 7))
#(h"9" & (select[3..0] == 6))
#(h"4" & (select[3..0] == 5))
#(h"0" & (select[3..0] == 4))
#(h"0" & (select[3..0] == 3))
#(h"0" & (select[3..0] == 2))
#(h"0" & (select[3..0] == 1))
#(h"0" & (select[3..0] == 0)));
diga[3..0] = ((h"3" & (select[3..0] == 15))
#(h"6" & (select[3..0] == 14))
#(h"3" & (select[3..0] == 13))
#(h"6" & (select[3..0] == 12))
#(h"8" & (select[3..0] == 11))
#(h"4" & (select[3..0] == 10))
#(h"2" & (select[3..0] == 9))
#(h"6" & (select[3..0] == 8))
#(h"4" & (select[3..0] == 7))
#(h"2" & (select[3..0] == 6))
#(h"4" & (select[3..0] == 5))
#(h"0" & (select[3..0] == 4))
#(h"0" & (select[3..0] == 3))
#(h"0" & (select[3..0] == 2))
#(h"0" & (select[3..0] == 1))
#(h"0" & (select[3..0] == 0)));
ledi[3..0] =
(h"f" & !txinv & disp_info & ledd3)
# (h"e" & txinv & disp_info & ledd3)
# (mode[7..4] & disp_info & ledd2)
# (mode[3..0] & disp_info & ledd1)
# (h"f" & !rxinv & disp_info & ledd0)
# (h"e" & rxinv & disp_info & ledd0)
# (digd[3..0] & disp_bps & ledd3)
# (digc[3..0] & disp_bps & ledd2)
# (digb[3..0] & disp_bps & ledd1)
# (diga[3..0] & disp_bps & ledd0)
# (errd[3..0] & disp_err & ledd3)
# (errc[3..0] & disp_err & ledd2)
# (errb[3..0] & disp_err & ledd1)
# (erra[3..0] & disp_err & ledd0);
led7 = ( ((ledd3 & (select[3..0] >= 13))
#(ledd1 & (select[3..0] < 13) & (select[3..0] >= 5))
#(ledd0 & (select[3..0] >= 13))) & disp_bps )
# ((ledd1 & mode_c7o & crlf & disp_info )
#(ledd1 & mode_c7e & crlf & disp_info )
#(ledd1 & mode_c8n & crlf & disp_info )
#(ledd0 & hfc & disp_info )
#(ledd3 & herrd & !lerrd & disp_err )
#(ledd2 & herrd & disp_err )
#(ledd1 & lerrd & disp_err )
#(ledd0 & !herrd & lerrd & disp_err )
);
led[6..0] = ((b"0000000" & (ledi[3..0] == 15))
#(b"1000000" & (ledi[3..0] == 14))
#(b"1010100" & (ledi[3..0] == 13))
#(b"0011100" & (ledi[3..0] == 12))
#(b"1110001" & (ledi[3..0] == 11))
#(b"1111001" & (ledi[3..0] == 10))
#(b"1101111" & (ledi[3..0] == 9))
#(b"1111111" & (ledi[3..0] == 8))
#(b"0000111" & (ledi[3..0] == 7))
#(b"1111101" & (ledi[3..0] == 6))
#(b"1101101" & (ledi[3..0] == 5))
#(b"1100110" & (ledi[3..0] == 4))
#(b"1001111" & (ledi[3..0] == 3))
#(b"1011011" & (ledi[3..0] == 2))
#(b"0000110" & (ledi[3..0] == 1))
#(b"0111111" & (ledi[3..0] == 0)));
_ledd[3..0] = !ledd[3..0];
ledd0 = (bdiv[6..5] == b"00");
ledd1 = (bdiv[6..5] == b"01");
ledd2 = (bdiv[6..5] == b"10");
ledd3 = (bdiv[6..5] == b"11");
mclk.clk = GLOBAL(fclk);
mclk = ((fdiv0 & (select[3..0] == 15))
#(fdiv1 & (select[3..0] == 14))
#(fdiv2 & (select[3..0] == 13))
#(fdiv3 & (select[3..0] == 12))
#(fdiv4 & (select[3..0] == 11))
#(fdiv5 & (select[3..0] == 10))
#(fdiv6 & (select[3..0] == 9))
#(fdiv7 & (select[3..0] == 8))
#(bdiv2 & (select[3..0] == 7))
#(bdiv3 & (select[3..0] == 6))
#(fdiv9 & (select[3..0] == 5))
#(bdiv4 & (select[3..0] == 4))
#(bdiv5 & (select[3..0] == 3))
#(bdiv6 & (select[3..0] == 2))
#(bdiv7 & (select[3..0] == 1))
#(bdiv8 & (select[3..0] == 0))
);
mclkd.clk = GLOBAL(fclk);
mclkd = mclk;
mstb = (mclk & !mclkd); -- master strobe : bit rate strobe
lfsr[22..0].clk = GLOBAL(fclk);
lfsr[22..0].ena = GLOBAL(mstb);
lfsr[22..1] = lfsr[21..0];
lfsr0 = (((lfsr8 $ lfsr4) # (lfsr[ 8..0] == 0)) & !none & !odd & txon)
#(((lfsr14 $ lfsr13) # (lfsr[14..0] == 0)) & !none & odd & txon)
#(((lfsr22 $ lfsr17) # (lfsr[22..0] == 0)) & none & !odd & txon);
sync.clk = GLOBAL(fclk);
sync.ena = GLOBAL(mstb);
sync = (stopbit & !test)
# (stopbit & test & none & odd)
# ((lfsr[8..0] == h"1ff") & test & !none & !odd)
# ((lfsr[14..0] == h"7fff") & test & !none & odd)
# ((lfsr[22..0] == h"7fffff") & test & none & !odd);
bclk.clk = GLOBAL(fclk);
bclk = mclk;
stopbit = (txcount[3..0] == 0);
ld = (stopbit & mstb & txon & ctsb);
txdata[7..0].clk = GLOBAL(fclk);
txdata[7..0].ena = ld;
txdata[7..0] =
( (txdata[7..0] + 1) & (txdata[7..0] >= h"20") & (txdata[7..0] < h"7e")
# (h"20" ) & (txdata[7..0] < h"20") & (txdata[7..0] != h"0d")
# (h"0d" ) & (txdata[7..0] >= h"7e") & crlf
# (h"0a" ) & (txdata[7..0] >= h"7e") & !crlf
# (h"0a" ) & (txdata[7..0] == h"0d")) & (!none # !odd)
# (txdata[7..0] + 1) & ( none & odd);
parity = (txdata0 $ txdata1)
$ (txdata2 $ txdata3)
$ (txdata4 $ txdata5 $ txdata6);
txd.clk = GLOBAL(fclk);
txd.ena = GLOBAL(mstb);
txd =
((((VCC & (tstate == stop ))
#(GND & (tstate == start))
#(txdata0 & (tstate == bit0 ))
#(txdata1 & (tstate == bit1 ))
#(txdata2 & (tstate == bit2 ))
#(txdata3 & (tstate == bit3 ))
#(txdata4 & (tstate == bit4 ))
#(txdata5 & (tstate == bit5 ))
#(txdata6 & (tstate == bit6 ))
#(txdata7 & mode_cff & (tstate == bit7))
#(!parity & mode_c7o & (tstate == bit7))
#( parity & mode_c7e & (tstate == bit7))
) & !test)
# (lfsr8 & mode_n9)
# (lfsr14 & mode_n15)
# (lfsr22 & mode_n23)
# (!txd & mode_pb & txon ));
txdb = txinv $ txd;
clrerr.clk = GLOBAL(fclk);
clrerr = (!txon # (!swd & swdd & !ccnt5));
(rerr, lerr, herr).clk = GLOBAL(fclk);
(rerr, lerr, herr).ena = GLOBAL(mstb);
rerr = !_rxd $ rxinv $ txd;
lerr.j = _rxd & (rxinv $ txd);
lerr.k = lerrd & ((!_rxd $ rxinv) == txd);
herr.j = !_rxd & (rxinv $ !txd);
herr.k = herrd & ((!_rxd $ rxinv) == txd);
(lerrd, herrd).clk = GLOBAL(fclk);
(lerrd, herrd).ena = kstb;
(lerrd, herrd) = (lerr, herr);
(erra[3..0], errb[3..0], errc[3..0], errd[3..0]).clk = GLOBAL(fclk);
(erra[3..0], errb[3..0], errc[3..0], errd[3..0]).clrn = !clrerr;
erra[3..0].ena = mstb & rerr;
erra[3..0] = (erra[3..0] + 1) & (erra[3..0] < 9);
errb[3..0].ena = mstb & rerr & (erra[3..0] == 9);
errb[3..0] = (errb[3..0] + 1) & (errb[3..0] < 9);
errc[3..0].ena = mstb & rerr & (errb[3..0] == 9) & (erra[3..0] == 9);
errc[3..0] = (errc[3..0] + 1) & (errc[3..0] < 9);
errd[3..0].ena = mstb & rerr
& (errc[3..0] == 9) & (errb[3..0] == 9) & (erra[3..0] == 9);
overflow = (errd[3..0] >= 10);
errd[3..0] = (errd[3..0] + 1) & !overflow
#(errd[3..0] ) & overflow;
tstate.clk = GLOBAL(fclk);
tstate.ena = GLOBAL(mstb);
CASE tstate IS
WHEN stop =>
IF (txon & ctsb) THEN
tstate = start;
ELSE
tstate = stop;
END IF;
WHEN start => tstate = bit0;
WHEN bit0 => tstate = bit1;
WHEN bit1 => tstate = bit2;
WHEN bit2 => tstate = bit3;
WHEN bit3 => tstate = bit4;
WHEN bit4 => tstate = bit5;
WHEN bit5 => tstate = bit6;
WHEN bit6 => tstate = bit7;
WHEN bit7 => tstate = stop;
END CASE;
END;