OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /w11/tags/w11a_V0.5/rtl/vlib/serport
    from Rev 3 to Rev 7
    Reverse comparison

Rev 3 → Rev 7

/tb/tb_serport_uart_rxtx.vhd
0,0 → 1,262
-- $Id: tb_serport_uart_rxtx.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_serport_uart_rxtx - sim
-- Description: Test bench for serport_uart_rxtx
--
-- Dependencies: simlib/simclk
-- tbd_serport_uart_rxtx [UUT]
--
-- To test: serport_uart_rxtx
--
-- Target Devices: generic
--
-- Verified (with tb_serport_uart_rxtx_stim.dat):
-- Date Rev Code ghdl ise Target Comment
-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok
-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
-- 2007-10-21 91 - 0.26 - - c:ok
-- 2007-10-14 89 - 0.26 - - c:ok
-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
-- 2007-10-12 88 - 0.26 - - c:ok
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-04-24 281 1.1.2 use direct instatiation for tbd_
-- 2008-03-24 129 1.1.1 CLK_CYCLE now 31 bits
-- 2007-10-21 91 1.1 now use 'send' command, self-checking (FAIL's)
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
-- 2007-08-27 76 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
use work.serport.all;
 
entity tb_serport_uart_rxtx is
end tb_serport_uart_rxtx;
 
architecture sim of tb_serport_uart_rxtx is
signal CLK : slbit := '0';
signal RESET : slbit := '0';
signal CLKDIV : slv13 := conv_std_logic_vector(15, 13);
signal RXDATA : slv8 := (others=>'0');
signal RXVAL : slbit := '0';
signal RXERR : slbit := '0';
signal RXACT : slbit := '0';
signal TXSD : slbit := '0';
signal TXDATA : slv8 := (others=>'0');
signal TXENA : slbit := '0';
signal TXBUSY : slbit := '0';
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : slv31 := (others=>'0');
signal N_MON_VAL : slbit := '0';
signal N_MON_DAT : slv8 := (others=>'0');
signal R_MON_VAL_1 : slbit := '0';
signal R_MON_DAT_1 : slv8 := (others=>'0');
signal R_MON_VAL_2 : slbit := '0';
signal R_MON_DAT_2 : slv8 := (others=>'0');
 
constant clock_period : time := 20 ns;
constant clock_offset : time := 200 ns;
constant setup_time : time := 5 ns;
constant c2out_time : time := 10 ns;
 
begin
 
SYSCLK : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_CYCLE => CLK_CYCLE,
CLK_STOP => CLK_STOP
);
 
UUT : entity work.tbd_serport_uart_rxtx
port map (
CLK => CLK,
RESET => RESET,
CLKDIV => CLKDIV,
RXSD => TXSD,
RXDATA => RXDATA,
RXVAL => RXVAL,
RXERR => RXERR,
RXACT => RXACT,
TXSD => TXSD,
TXDATA => TXDATA,
TXENA => TXENA,
TXBUSY => TXBUSY
);
 
 
proc_stim: process
file fstim : text open read_mode is "tb_serport_uart_rxtx_stim";
variable iline : line;
variable oline : line;
variable idelta : integer := 0;
variable itxdata : slv8 := (others=>'0');
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable irate : integer := 16;
 
begin
wait for clock_offset - setup_time;
 
file_loop: while not endfile(fstim) loop
 
readline (fstim, iline);
 
readcomment(iline, ok);
next file_loop when ok;
 
readword(iline, dname, ok);
if ok then
case dname is
when ".reset" => -- .reset
write(oline, string'(".reset"));
writeline(output, oline);
RESET <= '1';
wait for clock_period;
RESET <= '0';
wait for 9*clock_period;
 
when ".wait " => -- .wait
read_ea(iline, idelta);
wait for idelta*clock_period;
 
when ".rate " => -- .rate
read_ea(iline, irate);
CLKDIV <= conv_std_logic_vector(irate-1, 13);
when "send " => -- send
read_ea(iline, idelta);
read_ea(iline, itxdata);
while TXBUSY='1' loop
wait for clock_period;
end loop;
 
wait for idelta*clock_period;
 
writetimestamp(oline, CLK_CYCLE, ": send ");
write(oline, itxdata, right, 10);
writeline(output, oline);
 
TXDATA <= itxdata;
TXENA <= '1';
N_MON_VAL <= '1';
N_MON_DAT <= itxdata;
 
wait for clock_period;
TXENA <= '0';
N_MON_VAL <= '0';
when others => -- unknown command
write(oline, string'("?? unknown command: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
 
else
report "failed to find command" severity failure;
end if;
testempty_ea(iline);
end loop; -- file_loop
 
idelta := 0;
while TXBUSY='1' or RXACT='1' loop
wait for clock_period;
idelta := idelta + 1;
exit when idelta>3000;
end loop;
 
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
 
wait for 12*irate*clock_period;
 
CLK_STOP <= '1';
 
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
 
end process proc_stim;
 
proc_moni: process
variable oline : line;
begin
 
loop
wait until CLK'event and CLK='1';
 
if R_MON_VAL_1 = '1' then
if R_MON_VAL_2 = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, string'(" FAIL MISSING DATA="));
write(oline, R_MON_DAT_2);
writeline(output, oline);
end if;
R_MON_VAL_2 <= R_MON_VAL_1;
R_MON_DAT_2 <= R_MON_DAT_1;
end if;
R_MON_VAL_1 <= N_MON_VAL;
R_MON_DAT_1 <= N_MON_DAT;
 
if RXVAL='1' or RXERR='1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, RXDATA, right, 10);
if RXERR = '1' then
write(oline, string'(" RXERR=1"));
end if;
 
if R_MON_VAL_2 = '0' then
write(oline, string'(" FAIL UNEXPECTED"));
else
write(oline, string'(" CHECK"));
R_MON_VAL_2 <= '0';
if R_MON_DAT_2 = RXDATA and
RXERR='0' then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL"));
end if;
end if;
writeline(output, oline);
end if;
 
end loop;
end process proc_moni;
 
end sim;
/tb/tb_serport_uart_rx_ssim.vbom
0,0 → 1,4
# configure for _*sim case
tbd_serport_uart_rx = tbd_serport_uart_rx_ssim.vhd
tb_serport_uart_rx.vbom
@top:tb_serport_uart_rx
/tb/tbd_serport_uart_rxtx.vhd
0,0 → 1,87
-- $Id: tbd_serport_uart_rxtx.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbd_serport_uart_rxtx - syn
-- Description: Wrapper for serport_uart_rxtx to avoid records. It
-- has a port interface which will not be modified by xst
-- synthesis (no records, no generic port).
--
-- Dependencies: serport_uart_rxtx
--
-- To test: serport_uart_rxtx
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 69 122 0 - t 9.13
-- 2007-10-27 92 9.1 J30 xc3s1000-4 69 122 0 - t 9.13
-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 73 152 0 81 s 9.30
-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 73 125 0 - s 9.30
--
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 2007-10-21 91 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
use work.slvtypes.all;
use work.serport.all;
 
entity tbd_serport_uart_rxtx is -- serial port uart [tb design]
-- generic: CDWIDTH=13
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
CLKDIV : in slv13; -- clock divider setting
RXSD : in slbit; -- receive serial data (uart view)
RXDATA : out slv8; -- receiver data out
RXVAL : out slbit; -- receiver data valid
RXERR : out slbit; -- receiver data error (frame error)
RXACT : out slbit; -- receiver active
TXSD : out slbit; -- transmit serial data (uart view)
TXDATA : in slv8; -- transmit data in
TXENA : in slbit; -- transmit data enable
TXBUSY : out slbit -- transmit busy
);
end tbd_serport_uart_rxtx;
 
 
architecture syn of tbd_serport_uart_rxtx is
 
begin
 
UART : serport_uart_rxtx
generic map (
CDWIDTH => 13)
port map (
CLK => CLK,
RESET => RESET,
CLKDIV => CLKDIV,
RXSD => RXSD,
RXDATA => RXDATA,
RXVAL => RXVAL,
RXERR => RXERR,
RXACT => RXACT,
TXSD => TXSD,
TXDATA => TXDATA,
TXENA => TXENA,
TXBUSY => TXBUSY
);
end syn;
/tb/tb_serport_autobaud.vhd
0,0 → 1,292
-- $Id: tb_serport_autobaud.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_serport_autobaud - sim
-- Description: Test bench for serport_autobaud
--
-- Dependencies: simlib/simclk
-- tbd_serport_autobaud [UUT]
--
-- To test: serport_autobaud
--
-- Target Devices: generic
--
-- Verified (with tb_serport_autobaud_stim.dat):
-- Date Rev Code ghdl ise Target Comment
-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok
-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
-- 2007-10-21 91 - 0.26 - - c:ok
-- 2007-10-14 89 - 0.26 - - c:ok
-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok
-- 2007-10-12 88 - 0.26 - - c:ok
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-04-24 281 1.1.2 use direct instatiation for tbd_
-- 2008-03-24 129 1.1.1 CLK_CYCLE now 31 bits
-- 2007-10-21 91 1.1 now use 'send' command, self-checking (FAIL's)
-- 2007-10-14 89 1.1 add extra stop bit for CLKDIV=0; drop c2out wait;
-- add moni for autobauder
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
-- 2007-08-27 76 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
use work.serport.all;
 
entity tb_serport_autobaud is
end tb_serport_autobaud;
 
architecture sim of tb_serport_autobaud is
signal CLK : slbit := '0';
signal RESET : slbit := '0';
signal RXSD : slbit := '0';
signal CE_USEC : slbit := '0';
signal CE_MSEC : slbit := '0';
signal CLKDIV : slv13 := (others=>'0');
signal ABACT : slbit := '0';
signal ABDONE : slbit := '0';
signal RXDATA : slv8 := (others=>'0');
signal RXVAL : slbit := '0';
signal RXERR : slbit := '0';
signal RXACT : slbit := '0';
signal TXSD2 : slbit := '0';
signal RXDATA3 : slv8 := (others=>'0');
signal RXVAL3 : slbit := '0';
signal RXERR3 : slbit := '0';
signal RXACT3 : slbit := '0';
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : slv31 := (others=>'0');
signal N_MON_VAL : slbit := '0';
signal N_MON_DAT : slv8 := (others=>'0');
signal R_MON_VAL_1 : slbit := '0';
signal R_MON_DAT_1 : slv8 := (others=>'0');
signal R_MON_VAL_2 : slbit := '0';
signal R_MON_DAT_2 : slv8 := (others=>'0');
 
constant clock_period : time := 20 ns;
constant clock_offset : time := 200 ns;
constant setup_time : time := 5 ns;
constant c2out_time : time := 10 ns;
 
begin
 
SYSCLK : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_CYCLE => CLK_CYCLE,
CLK_STOP => CLK_STOP
);
 
UUT : entity work.tbd_serport_autobaud
port map (
CLK => CLK,
RESET => RESET,
RXSD => RXSD,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC,
CLKDIV => CLKDIV,
ABACT => ABACT,
ABDONE => ABDONE,
RXDATA => RXDATA,
RXVAL => RXVAL,
RXERR => RXERR,
RXACT => RXACT,
TXSD2 => TXSD2,
RXDATA3 => RXDATA3,
RXVAL3 => RXVAL3,
RXERR3 => RXERR3,
RXACT3 => RXACT3
);
 
 
proc_stim: process
file fstim : text open read_mode is "tb_serport_autobaud_stim";
variable iline : line;
variable oline : line;
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable idelta : integer := 0;
variable irate : integer := 16;
variable ival : slbit;
variable itxdata : slv8 := (others=>'0');
 
begin
 
RXSD <= '1';
wait for clock_offset - setup_time;
 
file_loop: while not endfile(fstim) loop
 
readline (fstim, iline);
 
readcomment(iline, ok);
next file_loop when ok;
 
readword(iline, dname, ok);
if ok then
case dname is
when ".reset" => -- .reset
write(oline, string'(".reset"));
writeline(output, oline);
RESET <= '1';
wait for clock_period;
RESET <= '0';
wait for 9*clock_period;
when ".break" => -- .break
read_ea(iline, idelta);
write(oline, string'(".break"));
writeline(output, oline);
RXSD <= '0';
wait for idelta*clock_period;
RXSD <= '1';
 
when ".wait " => -- .wait
read_ea(iline, idelta);
wait for idelta*clock_period;
 
when ".rate " => -- .rate
read_ea(iline, irate);
 
when "send " => -- send
read_ea(iline, ival);
read_ea(iline, itxdata);
writetimestamp(oline, CLK_CYCLE, ": send ");
write(oline, itxdata, right, 10);
writeline(output, oline);
 
RXSD <= '0'; -- start bit
N_MON_VAL <= ival;
N_MON_DAT <= itxdata;
wait for clock_period;
N_MON_VAL <= '0';
wait for (irate-1)*clock_period;
RXSD <= '1';
 
for i in itxdata'reverse_range loop -- transmit lsb first
RXSD <= itxdata(i); -- data bit
wait for irate*clock_period;
end loop;
RXSD <= '1'; -- stop bit (plus extra cycle)
wait for (irate+1)*clock_period;
 
when others => -- unknown command
write(oline, string'("?? unknown command: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
 
else
report "failed to find command" severity failure;
end if;
 
end loop;
 
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
 
wait for 25*irate*clock_period;
 
CLK_STOP <= '1';
 
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
 
end process proc_stim;
 
proc_moni: process
variable oline : line;
variable iabact : slbit := '0';
begin
 
loop
wait until CLK'event and CLK='1';
 
if R_MON_VAL_1 = '1' then
if R_MON_VAL_2 = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, string'(" FAIL MISSING DATA="));
write(oline, R_MON_DAT_2);
writeline(output, oline);
end if;
R_MON_VAL_2 <= R_MON_VAL_1;
R_MON_DAT_2 <= R_MON_DAT_1;
end if;
R_MON_VAL_1 <= N_MON_VAL;
R_MON_DAT_1 <= N_MON_DAT;
 
if (ABACT xor iabact)='1' then
writetimestamp(oline, CLK_CYCLE, ": auto ABACT =");
write(oline, ABACT, right, 2);
iabact := ABACT;
writeline(output, oline);
end if;
if ABDONE = '1' then
writetimestamp(oline, CLK_CYCLE, ": auto CLKDIV =");
write(oline, conv_integer(unsigned(CLKDIV)), right, 3);
writeline(output, oline);
end if;
if RXVAL='1' or (ABACT='0' and RXERR='1' and unsigned(RXDATA)/=0) then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, RXDATA, right, 10);
if RXERR = '1' then
write(oline, string'(" RXERR=1"));
end if;
 
if R_MON_VAL_2 = '0' then
write(oline, string'(" FAIL UNEXPECTED"));
else
write(oline, string'(" CHECK"));
R_MON_VAL_2 <= '0';
if R_MON_DAT_2 = RXDATA and
RXERR='0' then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL"));
end if;
end if;
writeline(output, oline);
end if;
 
end loop;
end process proc_moni;
 
end sim;
/tb/tb_serport_uart_rx.vbom
0,0 → 1,9
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../serport.vhd
# components
../../simlib/simclk.vbom
tbd_serport_uart_rx : tbd_serport_uart_rx.vbom
# design
tb_serport_uart_rx.vhd
/tb/tb_serport_uart_rx_stim.dat
0,0 → 1,529
# $Id: tb_serport_uart_rx_stim.dat 311 2010-06-30 17:52:37Z mueller $
#
#
C setting rate=1 -> CLKDIV=0 ------------------------------------------------
.wait 5
.rate 1
C test frame error (send 7,8,9,10 '0' bits, followed by 10 '1' bits)
puls 1 0 11000000 0 7 1 10 -- VAL=1 ERR=0 DAT=11000000
puls 1 0 10000000 0 8 1 10 -- VAL=1 ERR=0 DAT=10000000
puls 1 0 00000000 0 9 1 10 -- VAL=1 ERR=0 DAT=00000000
puls 1 1 00000000 0 10 1 10 -- VAL=1 ERR=1 DAT=00000000
C test 1 stop bits
puls 1 0 00000000 0 9 1 1 -- 1 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 9 -- 1 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 9 1 1 -- 1 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 9 -- 1 stop bit VAL=1 ERR=0 DAT=11111111
C test 2 stop bits
puls 1 0 00000000 0 9 1 2 -- 2 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 10 -- 2 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 9 1 2 -- 2 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 10 -- 2 stop bit VAL=1 ERR=0 DAT=11111111
C test 3 stop bits
puls 1 0 00000000 0 9 1 3 -- 3 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 11 -- 3 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 9 1 3 -- 3 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 11 -- 3 stop bit VAL=1 ERR=0 DAT=11111111
C test 4 stop bits
puls 1 0 00000000 0 9 1 4 -- 4 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 12 -- 4 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 9 1 4 -- 4 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 1 1 12 -- 4 stop bit VAL=1 ERR=0 DAT=11111111
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 00000001
send 1 00000010
send 1 00000100
send 1 00001000
send 1 00010000
send 1 00100000
send 1 01000000
send 1 10000000
send 1 11111110
send 1 11111101
send 1 11111011
send 1 11110111
send 1 11101111
send 1 11011111
send 1 10111111
send 1 01111111
send 1 00000000
send 1 11111111
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
C test data with 3 stop bits
send 2 00000000
send 2 00000001
send 2 00000010
send 2 00000100
send 2 00001000
send 2 00010000
send 2 00100000
send 2 01000000
send 2 10000000
send 2 11111110
send 2 11111101
send 2 11111011
send 2 11110111
send 2 11101111
send 2 11011111
send 2 10111111
send 2 01111111
send 2 00000000
send 2 11111111
send 2 00000011
send 2 00001100
send 2 00110000
send 2 11000000
#
C setting rate=2 -> CLKDIV=1 ------------------------------------------------
.wait 5
.rate 2
C test frame error (send 16,17,18,19,20 '0' bits, followed by 10 '1' bits)
puls 1 0 10000000 0 16 1 10 -- VAL=1 ERR=0 DAT=10000000
puls 1 0 10000000 0 17 1 10 -- VAL=1 ERR=0 DAT=10000000
puls 1 0 00000000 0 18 1 10 -- VAL=1 ERR=0 DAT=00000000
puls 1 0 00000000 0 19 1 10 -- VAL=1 ERR=0 DAT=00000000
puls 1 1 00000000 0 20 1 10 -- VAL=1 ERR=1 DAT=00000000
C test 1 stop bits
puls 1 0 00000000 0 18 1 2 -- 1 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 18 -- 1 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 18 1 2 -- 1 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 18 -- 1 stop bit VAL=1 ERR=0 DAT=11111111
C test 2 stop bits
puls 1 0 00000000 0 18 1 4 -- 2 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 20 -- 2 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 18 1 4 -- 2 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 20 -- 2 stop bit VAL=1 ERR=0 DAT=11111111
C test 3 stop bits
puls 1 0 00000000 0 18 1 6 -- 3 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 22 -- 3 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 18 1 6 -- 3 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 22 -- 3 stop bit VAL=1 ERR=0 DAT=11111111
C test 4 stop bits
puls 1 0 00000000 0 18 1 8 -- 4 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 24 -- 4 stop bit VAL=1 ERR=0 DAT=11111111
puls 1 0 00000000 0 18 1 8 -- 4 stop bit VAL=1 ERR=0 DAT=00000000
puls 1 0 11111111 0 2 1 24 -- 4 stop bit VAL=1 ERR=0 DAT=11111111
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 00000001
send 1 00000010
send 1 00000100
send 1 00001000
send 1 00010000
send 1 00100000
send 1 01000000
send 1 10000000
send 1 11111110
send 1 11111101
send 1 11111011
send 1 11110111
send 1 11101111
send 1 11011111
send 1 10111111
send 1 01111111
send 1 00000000
send 1 11111111
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
C test data with 3 stop bits
send 2 00000000
send 2 00000001
send 2 00000010
send 2 00000100
send 2 00001000
send 2 00010000
send 2 00100000
send 2 01000000
send 2 10000000
send 2 11111110
send 2 11111101
send 2 11111011
send 2 11110111
send 2 11101111
send 2 11011111
send 2 10111111
send 2 01111111
send 2 00000000
send 2 11111111
send 2 00000011
send 2 00001100
send 2 00110000
send 2 11000000
#
C setting rate=4 -> CLKDIV=3 ------------------------------------------------
.wait 5
.rate 4
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 00000001
send 1 00000010
send 1 00000100
send 1 00001000
send 1 00010000
send 1 00100000
send 1 01000000
send 1 10000000
send 1 11111110
send 1 11111101
send 1 11111011
send 1 11110111
send 1 11101111
send 1 11011111
send 1 10111111
send 1 01111111
send 1 00000000
send 1 11111111
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
#
C setting rate=16 -> CLKDIV=15 -----------------------------------------------
.wait 5
.rate 16
#
C test resonse to start bit runts
puls 0 0 00000000 0 1 1 20 -- will recover fast
puls 0 0 00000000 0 2 1 20 -- "
puls 0 0 00000000 0 3 1 20
puls 0 0 00000000 0 4 1 20
puls 0 0 00000000 0 6 1 20
puls 1 0 11111111 0 10 1 200 -- will be taken as start bit
#
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 11110000
send 1 00001111
send 1 11111111
C test data with 3 stop bits
send 2 00000000
send 2 11110000
send 2 00001111
send 2 11111111
C test data with 4 stop bits
send 3 00000000
send 3 11110000
send 3 00001111
send 3 11111111
#
C setting rate=32 -> CLKDIV=31 -----------------------------------------------
.wait 5
.rate 32
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 11110000
send 1 00001111
send 1 11111111
C test data with 3 stop bits
send 2 00000000
send 2 11110000
send 2 00001111
send 2 11111111
C test data with 4 stop bits
send 3 00000000
send 3 11110000
send 3 00001111
send 3 11111111
#
C setting rate=32 -> CLKDIV=31 ---- txrate = 31 !! ---------------------------
.wait 5
.rate 32
.xrate 31
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 11110000
send 1 00001111
send 1 11111111
C test data with 3 stop bits
send 2 00000000
send 2 11110000
send 2 00001111
send 2 11111111
C test data with 4 stop bits
send 3 00000000
send 3 11110000
send 3 00001111
send 3 11111111
#
C setting rate=32 -> CLKDIV=31 ---- txrate = 33 !! ---------------------------
.wait 5
.rate 32
.xrate 33
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 11110000
send 1 00001111
send 1 11111111
C test data with 3 stop bits
send 2 00000000
send 2 11110000
send 2 00001111
send 2 11111111
C test data with 4 stop bits
send 3 00000000
send 3 11110000
send 3 00001111
send 3 11111111
#
C setting rate=27 -> CLKDIV=25 ---- txrate = 26 !! ---------------------------
.wait 5
.rate 27
.xrate 26
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 11110000
send 1 00001111
send 1 11111111
C test data with 3 stop bits
send 2 00000000
send 2 11110000
send 2 00001111
send 2 11111111
C test data with 4 stop bits
send 3 00000000
send 3 11110000
send 3 00001111
send 3 11111111
#
C setting rate=27 -> CLKDIV=27 ---- txrate = 28 !! ---------------------------
.wait 5
.rate 27
.xrate 28
C test back-to-back data
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 0 00001000
send 0 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111110
send 0 11111101
send 0 11111011
send 0 11110111
send 0 11101111
send 0 11011111
send 0 10111111
send 0 01111111
send 0 00000000
send 0 11111111
send 0 00000011
send 0 00001100
send 0 00110000
send 0 11000000
C test data with 2 stop bits
send 1 00000000
send 1 11110000
send 1 00001111
send 1 11111111
C test data with 3 stop bits
send 2 00000000
send 2 11110000
send 2 00001111
send 2 11111111
C test data with 4 stop bits
send 3 00000000
send 3 11110000
send 3 00001111
send 3 11111111
#
/tb/tbd_serport_autobaud.vhd
0,0 → 1,152
-- $Id: tbd_serport_autobaud.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbd_serport_autobaud - syn
-- Description: Wrapper for serport_uart_autobaud and serport_uart_rxtx to
-- avoid records. It has a port interface which will not be
-- modified by xst synthesis (no records, no generic port).
--
-- Dependencies: clkdivce
-- serport_uart_autobaud
-- serport_uart_rxtx
-- serport_uart_rx
--
-- To test: serport_uart_autobaud
-- serport_uart_rxtx
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 151 291 0 - t 9.23
-- 2007-10-27 92 9.1 J30 xc3s1000-4 151 291 0 - t 9.23
-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 153 338 0 178 s 9.45
-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 152 293 0 - s 9.40
--
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 2008-01-20 112 1.0.1 rename clkgen->clkdivce
-- 2007-06-24 60 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
use work.slvtypes.all;
use work.genlib.all;
use work.serport.all;
 
entity tbd_serport_autobaud is -- serial port autobaud [tb design]
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
RXSD : in slbit; -- receive serial data (uart view)
CE_USEC : out slbit; -- usec pulse (here every 4 clocks)
CE_MSEC : out slbit; -- msec pulse (here every 20 clocks)
CLKDIV : out slv13; -- clock divider setting
ABACT : out slbit; -- autobaud active
ABDONE : out slbit; -- autobaud done
RXDATA : out slv8; -- receiver data out (1st rx)
RXVAL : out slbit; -- receiver data valid (1st rx)
RXERR : out slbit; -- receiver data error (1st rx)
RXACT : out slbit; -- receiver active (1st rx)
TXSD2 : out slbit; -- transmit serial data (2nd tx)
RXDATA3 : out slv8; -- receiver data out (3rd rx)
RXVAL3 : out slbit; -- receiver data valid (3rd rx)
RXERR3 : out slbit; -- receiver data error (3rd rx)
RXACT3 : out slbit -- receiver active (3rd rx)
);
end tbd_serport_autobaud;
 
 
architecture syn of tbd_serport_autobaud is
 
constant cdwidth : positive := 13;
 
signal LCE_MSEC : slbit := '0';
signal LCLKDIV : slv13 := (others=>'0');
signal LRXDATA : slv8 := (others=>'0');
signal LRXVAL : slbit := '0';
signal LTXSD2 : slbit := '0';
signal LABACT : slbit := '0';
begin
 
CKLDIV : clkdivce
generic map (
CDUWIDTH => 6,
USECDIV => 4,
MSECDIV => 5)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => LCE_MSEC
);
AUTOBAUD : serport_uart_autobaud
generic map (
CDWIDTH => cdwidth,
CDINIT => 15)
port map (
CLK => CLK,
CE_MSEC => LCE_MSEC,
RESET => RESET,
RXSD => RXSD,
CLKDIV => LCLKDIV,
ACT => LABACT,
DONE => ABDONE
);
UART1 : serport_uart_rxtx
generic map (
CDWIDTH => cdwidth)
port map (
CLK => CLK,
RESET => LABACT,
CLKDIV => LCLKDIV,
RXSD => RXSD,
RXDATA => LRXDATA,
RXVAL => LRXVAL,
RXERR => RXERR,
RXACT => RXACT,
TXSD => LTXSD2,
TXDATA => LRXDATA,
TXENA => LRXVAL,
TXBUSY => open
);
UART2 : serport_uart_rx
generic map (
CDWIDTH => cdwidth)
port map (
CLK => CLK,
RESET => LABACT,
CLKDIV => LCLKDIV,
RXSD => LTXSD2,
RXDATA => RXDATA3,
RXVAL => RXVAL3,
RXERR => RXERR3,
RXACT => RXACT3
);
 
CE_MSEC <= LCE_MSEC;
CLKDIV <= LCLKDIV;
ABACT <= LABACT;
RXDATA <= LRXDATA;
RXVAL <= LRXVAL;
TXSD2 <= LTXSD2;
end syn;
/tb/tbd_serport_uart_rx.vbom
0,0 → 1,7
# libs
../../slvtypes.vhd
../serport.vhd
# components
../serport_uart_rx.vbom
# design
tbd_serport_uart_rx.vhd
/tb/tb_serport_uart_rxtx_ssim.vbom
0,0 → 1,4
# configure for _*sim case
tbd_serport_uart_rxtx = tbd_serport_uart_rxtx_ssim.vhd
tb_serport_uart_rxtx.vbom
@top:tb_serport_uart_rxtx
/tb/tb_serport_autobaud_ssim.vbom
0,0 → 1,4
# configure for _*sim case
tbd_serport_autobaud = tbd_serport_autobaud_ssim.vhd
tb_serport_autobaud.vbom
@top:tb_serport_autobaud
/tb/tb_serport_uart_rxtx.vbom
0,0 → 1,9
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../serport.vhd
# components
../../simlib/simclk.vbom
tbd_serport_uart_rxtx : tbd_serport_uart_rxtx.vbom
# design
tb_serport_uart_rxtx.vhd
/tb/tb_serport_uart_rxtx_stim.dat
0,0 → 1,57
# $Id: tb_serport_uart_rxtx_stim.dat 311 2010-06-30 17:52:37Z mueller $
#
#
C ----------------------------------------------------------------------------
C with startup setting rate=16 -> CLKDIV=15
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 10 00001000
send 50 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111111
send 0 11001100
send 0 00110011
#
C ----------------------------------------------------------------------------
# wait >16*10 cycles
.wait 200
C now try rate=2 -> CLKDIV=1
.rate 2
.reset
.wait 20
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 10 00001000
send 50 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111111
send 0 11001100
send 0 00110011
#
C ----------------------------------------------------------------------------
# wait >2*10 cycles
.wait 30
C now try rate=1 -> CLKDIV=0
.rate 1
.reset
.wait 20
send 0 00000000
send 0 00000001
send 0 00000010
send 0 00000100
send 10 00001000
send 50 00010000
send 0 00100000
send 0 01000000
send 0 10000000
send 0 11111111
send 0 11001100
send 0 00110011
/tb/tb_serport_uart_rx.vhd
0,0 → 1,328
-- $Id: tb_serport_uart_rx.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_serport_uart_rx - sim
-- Description: Test bench for serport_uart_rx
--
-- Dependencies: simlib/simclk
-- tbd_serport_uart_rx [UUT]
--
-- To test: serport_uart_rx
--
-- Target Devices: generic
--
-- Verified (with tb_serport_uart_rx_stim.dat):
-- Date Rev Code ghdl ise Target Comment
-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok
-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok (63488 cl 15.21s)
-- 2007-10-21 91 - 0.26 - - c:ok (63488 cl 7.12s)
--
-- Revision History:
-- Date Rev Version Comment
-- 2010-04-24 281 1.0.2 use direct instatiation for tbd_
-- 2008-03-24 129 1.0.1 CLK_CYCLE now 31 bits
-- 2007-10-21 91 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
use work.serport.all;
 
entity tb_serport_uart_rx is
end tb_serport_uart_rx;
 
architecture sim of tb_serport_uart_rx is
signal CLK : slbit := '0';
signal RESET : slbit := '0';
signal CLKDIV : slv5 := conv_std_logic_vector(15, 5);
signal RXSD : slbit := '1';
signal RXDATA : slv8 := (others=>'0');
signal RXVAL : slbit := '0';
signal RXERR : slbit := '0';
signal RXACT : slbit := '0';
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : slv31 := (others=>'0');
 
signal N_MON_VAL : slbit := '0';
signal N_MON_ERR : slbit := '0';
signal N_MON_DAT : slv8 := (others=>'0');
signal R_MON_VAL_1 : slbit := '0';
signal R_MON_ERR_1 : slbit := '0';
signal R_MON_DAT_1 : slv8 := (others=>'0');
signal R_MON_VAL_2 : slbit := '0';
signal R_MON_ERR_2 : slbit := '0';
signal R_MON_DAT_2 : slv8 := (others=>'0');
constant clock_period : time := 20 ns;
constant clock_offset : time := 200 ns;
constant setup_time : time := 5 ns;
constant c2out_time : time := 10 ns;
 
begin
 
SYSCLK : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_CYCLE => CLK_CYCLE,
CLK_STOP => CLK_STOP
);
 
UUT : entity work.tbd_serport_uart_rx
port map (
CLK => CLK,
RESET => RESET,
CLKDIV => CLKDIV,
RXSD => RXSD,
RXDATA => RXDATA,
RXVAL => RXVAL,
RXERR => RXERR,
RXACT => RXACT
);
 
 
proc_stim: process
file fstim : text open read_mode is "tb_serport_uart_rx_stim";
variable iline : line;
variable oline : line;
variable idelta : integer := 0;
variable itxdata : slv8 := (others=>'0');
variable irxval : slbit := '0';
variable irxerr : slbit := '0';
variable irxdata : slv8 := (others=>'0');
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable irate : integer := 16;
 
type bit_10_array_type is array (0 to 9) of slbit;
type int_10_array_type is array (0 to 9) of integer;
variable valpuls : bit_10_array_type := (others=>'0');
variable delpuls : int_10_array_type := (others=>0);
variable npuls : integer := 0;
begin
 
wait for clock_offset - setup_time;
file_loop: while not endfile(fstim) loop
 
readline (fstim, iline);
 
readcomment(iline, ok);
next file_loop when ok;
 
readword(iline, dname, ok);
if ok then
case dname is
when ".reset" => -- .reset
write(oline, string'(".reset"));
writeline(output, oline);
RESET <= '1';
wait for clock_period;
RESET <= '0';
wait for 9*clock_period;
 
when ".wait " => -- .wait
read_ea(iline, idelta);
wait for idelta*clock_period;
 
when ".rate " => -- .rate
idelta := 0;
while RXACT='1' loop -- ensure that uart isn't active
wait for clock_period;
idelta := idelta + 1;
exit when idelta>3000;
end loop;
read_ea(iline, irate);
wait for 2*clock_period;
CLKDIV <= conv_std_logic_vector(irate-1, CLKDIV'length);
wait for 2*clock_period;
when ".xrate" => -- .xrate
read_ea(iline, irate);
when "puls " => -- puls
writetimestamp(oline, CLK_CYCLE, ": puls ");
 
read_ea(iline, irxval);
read_ea(iline, irxerr);
read_ea(iline, irxdata);
 
npuls := 0;
for i in valpuls'range loop
testempty(iline, ok);
if ok then
exit;
end if;
read_ea(iline, valpuls(i));
read_ea(iline, delpuls(i));
assert delpuls(i)>0
report "assert puls length > 0" severity failure;
npuls := npuls + 1;
write(oline, valpuls(i), right, 3);
write(oline, delpuls(i), right, 3);
end loop; -- i
writeline(output, oline);
 
if npuls > 0 then
N_MON_VAL <= irxval;
N_MON_ERR <= irxerr;
N_MON_DAT <= irxdata;
for i in 0 to npuls-1 loop
RXSD <= valpuls(i);
wait for clock_period;
N_MON_VAL <= '0';
wait for (delpuls(i)-1)*clock_period;
end loop; -- i
end if;
when "send " => -- send
read_ea(iline, idelta);
read_ea(iline, itxdata);
 
RXSD <= '1';
wait for idelta*clock_period;
 
writetimestamp(oline, CLK_CYCLE, ": send ");
write(oline, itxdata, right, 10);
writeline(output, oline);
 
N_MON_VAL <= '1';
N_MON_ERR <= '0';
N_MON_DAT <= itxdata;
 
RXSD <= '0'; -- start bit
wait for clock_period;
N_MON_VAL <= '0';
wait for (irate-1)*clock_period;
RXSD <= '1';
 
for i in itxdata'reverse_range loop -- transmit lsb first
RXSD <= itxdata(i); -- data bit
wait for irate*clock_period;
end loop;
RXSD <= '1'; -- stop bit
wait for irate*clock_period;
 
when others => -- unknown command
write(oline, string'("?? unknown command: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
 
else
report "failed to find command" severity failure;
end if;
testempty_ea(iline);
end loop; -- file_loop:
 
idelta := 0;
while RXACT='1' loop
wait for clock_period;
idelta := idelta + 1;
exit when idelta>3000;
end loop;
 
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
 
wait for 12*irate*clock_period;
 
CLK_STOP <= '1';
 
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
 
end process proc_stim;
 
proc_moni: process
variable oline : line;
begin
 
loop
wait until CLK'event and CLK='1';
 
if R_MON_VAL_1 = '1' then
if R_MON_VAL_2 = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, string'(" FAIL MISSING ERR="));
write(oline, R_MON_ERR_2);
write(oline, string'(" DATA="));
write(oline, R_MON_DAT_2);
writeline(output, oline);
end if;
R_MON_VAL_2 <= R_MON_VAL_1;
R_MON_ERR_2 <= R_MON_ERR_1;
R_MON_DAT_2 <= R_MON_DAT_1;
end if;
R_MON_VAL_1 <= N_MON_VAL;
R_MON_ERR_1 <= N_MON_ERR;
R_MON_DAT_1 <= N_MON_DAT;
 
if RXVAL='1' or RXERR='1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
write(oline, RXDATA, right, 10);
if RXERR = '1' then
write(oline, string'(" RXERR=1"));
end if;
 
if R_MON_VAL_2 = '0' then
write(oline, string'(" FAIL UNEXPECTED"));
else
write(oline, string'(" CHECK"));
R_MON_VAL_2 <= '0';
if R_MON_ERR_2 = '0' then
if R_MON_DAT_2 = RXDATA and
RXERR='0' then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL"));
end if;
 
else
if RXERR = '1' then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL, RXERR=1 expected"));
end if;
end if;
end if;
writeline(output, oline);
end if;
end loop;
end process proc_moni;
 
end sim;
/tb/tbd_serport_uart_rxtx.vbom
0,0 → 1,7
# libs
../../slvtypes.vhd
../serport.vhd
# components
../serport_uart_rxtx.vbom
# design
tbd_serport_uart_rxtx.vhd
/tb/tb_serport_autobaud.vbom
0,0 → 1,9
# libs
../../slvtypes.vhd
../../simlib/simlib.vhd
../serport.vhd
# components
../../simlib/simclk.vbom
tbd_serport_autobaud : tbd_serport_autobaud.vbom
# design
tb_serport_autobaud.vhd
/tb/tb_serport_autobaud_stim.dat
0,0 → 1,77
# $Id: tb_serport_autobaud_stim.dat 311 2010-06-30 17:52:37Z mueller $
#
#
C ----------------------------------------------------------------------------
C start without autobauding and default setup clock divisor of 16 (CLKDIV=15)
.reset
.rate 16
.wait 5
send 1 00000001
send 1 10000000
#
C ----------------------------------------------------------------------------
C now break + autobaud with clock divisor = 8 (CLKDIV=7)
.break 3000
.wait 20
.rate 8
send 0 10000000
send 1 10000000
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
#
C ----------------------------------------------------------------------------
C now break + autobaud with clock divisor = 4 (CLKDIV=3)
.break 3000
.wait 20
.rate 4
send 0 10000000
send 1 10000000
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
#
C ----------------------------------------------------------------------------
C now break + autobaud with clock divisor = 2 (CLKDIV=1)
.break 3000
.wait 20
.rate 2
send 0 10000000
send 1 10000000
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
#
C ----------------------------------------------------------------------------
C now break + autobaud with clock divisor = 1 (CLKDIV=0)
.break 3000
.wait 20
.rate 1
send 0 10000000
send 1 10000000
send 1 01000000
send 1 00100000
send 1 00010000
send 1 00001000
send 1 00000100
send 1 00000010
send 1 00000001
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
#
C ----------------------------------------------------------------------------
C now break + autobaud with clock divisor = 32 (CLKDIV=31)
.break 3000
.wait 20
.rate 32
send 0 10000000
send 1 10000000
send 1 00000011
send 1 00001100
send 1 00110000
send 1 11000000
/tb/tbd_serport_uart_rx.vhd
0,0 → 1,79
-- $Id: tbd_serport_uart_rx.vhd 314 2010-07-09 17:38:41Z mueller $
--
-- Copyright 2007- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbd_serport_uart_rx - syn
-- Description: Wrapper for serport_uart_rx to avoid records. It
-- has a port interface which will not be modified by xst
-- synthesis (no records, no generic port).
--
-- Dependencies: serport_uart_rx
--
-- To test: serport_uart_rx
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 26 67 0 - t 8.17
-- 2007-10-27 92 9.1 J30 xc3s1000-4 26 67 0 - t 8.25
-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 29 90 0 47 s 8.45
-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 31 92 0 - s 8.25
--
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
-- Revision History:
-- Date Rev Version Comment
-- 2007-10-21 91 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
use work.slvtypes.all;
use work.serport.all;
 
entity tbd_serport_uart_rx is -- serial port uart rx [tb design]
-- generic: CDWIDTH=5
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
CLKDIV : in slv5; -- clock divider setting
RXSD : in slbit; -- receive serial data (uart view)
RXDATA : out slv8; -- receiver data out
RXVAL : out slbit; -- receiver data valid
RXERR : out slbit; -- receiver data error (frame error)
RXACT : out slbit -- receiver active
);
end tbd_serport_uart_rx;
 
 
architecture syn of tbd_serport_uart_rx is
 
begin
 
UART : serport_uart_rx
generic map (
CDWIDTH => 5)
port map (
CLK => CLK,
RESET => RESET,
CLKDIV => CLKDIV,
RXSD => RXSD,
RXDATA => RXDATA,
RXVAL => RXVAL,
RXERR => RXERR,
RXACT => RXACT
);
end syn;
/tb/.cvsignore
0,0 → 1,15
tb_serport_autobaud
tb_serport_autobaud_stim
tb_serport_autobaud_[sft]sim
tb_serport_autobaud_ISim
tb_serport_autobaud_ISim_[sft]sim
tb_serport_uart_rx
tb_serport_uart_rx_stim
tb_serport_uart_rx_[sft]sim
tb_serport_uart_rx_ISim
tb_serport_uart_rx_ISim_[sft]sim
tb_serport_uart_rxtx
tb_serport_uart_rxtx_stim
tb_serport_uart_rxtx_[sft]sim
tb_serport_uart_rxtx_ISim
tb_serport_uart_rxtx_ISim_[sft]sim
/tb/Makefile
0,0 → 1,30
# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2009-11-21 252 1.2 add ISim support
# 2007-11-26 98 1.1 use make includes
# 2007-06-03 48 1.0 Initial version
#
EXE_all = tb_serport_uart_rx tb_serport_uart_rxtx tb_serport_autobaud
#
.phony : all all_ssim all_tsim clean
#
all : $(EXE_all)
all_ssim : $(EXE_all:=_ssim)
all_tsim : $(EXE_all:=_tsim)
#
clean : ise_clean ghdl_clean isim_clean
#
#-----
#
include $(RETROBASE)/rtl/vlib/Makefile.ghdl
include $(RETROBASE)/rtl/vlib/Makefile.isim
include $(RETROBASE)/rtl/vlib/Makefile.xflow
#
VBOM_all = $(wildcard *.vbom)
#
include $(VBOM_all:.vbom=.dep_xst)
include $(VBOM_all:.vbom=.dep_ghdl)
include $(VBOM_all:.vbom=.dep_isim)
#
/tb/tbd_serport_autobaud.vbom
0,0 → 1,11
# libs
../../slvtypes.vhd
../../genlib/genlib.vhd
../serport.vhd
# components
../../genlib/clkdivce.vbom
../serport_uart_autobaud.vbom
../serport_uart_rxtx.vbom
../serport_uart_rx.vbom
# design
tbd_serport_autobaud.vhd
/tb
tb Property changes : Added: svn:ignore ## -0,0 +1,47 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log +tb_serport_autobaud +tb_serport_autobaud_stim +tb_serport_autobaud_[sft]sim +tb_serport_autobaud_ISim +tb_serport_autobaud_ISim_[sft]sim +tb_serport_uart_rx +tb_serport_uart_rx_stim +tb_serport_uart_rx_[sft]sim +tb_serport_uart_rx_ISim +tb_serport_uart_rx_ISim_[sft]sim +tb_serport_uart_rxtx +tb_serport_uart_rxtx_stim +tb_serport_uart_rxtx_[sft]sim +tb_serport_uart_rxtx_ISim +tb_serport_uart_rxtx_ISim_[sft]sim Index: serport_uart_autobaud.vbom =================================================================== --- serport_uart_autobaud.vbom (nonexistent) +++ serport_uart_autobaud.vbom (revision 7) @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +serport_uart_autobaud.vhd Index: serport_uart_rxtx.vbom =================================================================== --- serport_uart_rxtx.vbom (nonexistent) +++ serport_uart_rxtx.vbom (revision 7) @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +serport.vhd +# components +serport_uart_rx.vbom +serport_uart_tx.vbom +# design +serport_uart_rxtx.vhd Index: serport_uart_rxtx_ab.vhd =================================================================== --- serport_uart_rxtx_ab.vhd (nonexistent) +++ serport_uart_rxtx_ab.vhd (revision 7) @@ -0,0 +1,100 @@ +-- $Id: serport_uart_rxtx_ab.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_rxtx_ab - syn +-- Description: serial port UART - transmitter-receiver + autobauder +-- +-- Dependencies: serport_uart_autobaud +-- serport_uart_rxtx +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.serport.all; + +entity serport_uart_rxtx_ab is -- serial port uart: rx+tx+autobaud + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit; -- transmit busy + ABACT : out slbit; -- autobaud active; if 1 clkdiv invalid + ABDONE : out slbit -- autobaud resync done + ); +end serport_uart_rxtx_ab; + +architecture syn of serport_uart_rxtx_ab is + + signal CLKDIV : slv(CDWIDTH-1 downto 0) := conv_std_logic_vector(0, CDWIDTH); + signal ABACT_L : slbit := '0'; -- local readable copy of ABACT + signal UART_RESET : slbit := '0'; + +begin + + AB : serport_uart_autobaud + generic map ( + CDWIDTH => CDWIDTH, + CDINIT => CDINIT) + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + CLKDIV => CLKDIV, + ACT => ABACT_L, + DONE => ABDONE + ); + + UART_RESET <= ABACT_L or RESET; + ABACT <= ABACT_L; + + RXTX : serport_uart_rxtx + generic map ( + CDWIDTH => CDWIDTH) + port map ( + CLK => CLK, + RESET => UART_RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + +end syn; Index: serport_uart_rx.vhd =================================================================== --- serport_uart_rx.vhd (nonexistent) +++ serport_uart_rx.vhd (revision 7) @@ -0,0 +1,312 @@ +-- $Id: serport_uart_rx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2009 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +-- The uart expects CLKDIV+1 wide input bit symbols. +-- This implementation counts the number of 1's in the first CLKDIV clock +-- cycles, and checks in the last cycle of the symbol time whether the +-- number of 1's was > CLKDIV/2. This supresses short glitches nicely, +-- especially for larger clock dividers. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_rx - syn +-- Description: serial port UART - receiver +-- +-- Dependencies: - +-- Test bench: tb/tb_serport_uart_rxtx +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2009-07-12 233 2.0.2 remove snoopers +-- 2008-03-02 121 2.0.1 comment out snoopers +-- 2007-10-21 91 2.0 re-designed and -implemented with state machine. +-- allow CLKDIV=0 with 1 stop bit; allow max. CLKDIV +-- (all 1's); aborts bad start bit after 1/2 cell; +-- accepts stop bit after 1/2 cell, permits tx clock +-- be ~3 percent faster than rx clock. +-- for 3s1000ft256: 50 -> 58 slices for CDWIDTH=13 +-- 2007-10-14 89 1.1 almost full rewrite, handles now CLKDIV=0 properly +-- for 3s1000ft256: 43 -> 50 slices for CDWIDTH=13 +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +-- synthesis translate_off +use ieee.std_logic_textio.all; +use std.textio.all; +-- synthesis translate_on + +use work.slvtypes.all; + +entity serport_uart_rx is -- serial port uart: receive part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit -- receiver active + ); +end serport_uart_rx; + + +architecture syn of serport_uart_rx is + + type state_type is ( + s_idle, -- s_idle: idle + s_colb0, -- s_colb0: collect b0 (start bit) + s_endb0, -- s_endb0: finish b0 (start bit) + s_colbx, -- s_colbx: collect bx + s_endbx, -- s_endbx: finish bx + s_colb9, -- s_colb9: collect bx (stop bit) + s_endb9 -- s_endb9: finish bx (stop bit) + ); + + type regs_type is record + state : state_type; -- state + ccnt : slv(CDWIDTH-1 downto 0); -- clock divider counter + dcnt : slv(CDWIDTH downto 0); -- data '1' counter + bcnt : slv4; -- bit counter + sreg : slv8; -- input shift register + end record regs_type; + + constant ccntzero : slv(CDWIDTH-1 downto 0) := (others=>'0'); + constant dcntzero : slv(CDWIDTH downto 0) := (others=>'0'); + constant regs_init : regs_type := ( + s_idle, + ccntzero, + dcntzero, + (others=>'0'), + (others=>'0') + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RESET, CLKDIV, RXSD) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable dbit : slbit := '0'; + variable ld_ccnt : slbit := '0'; + variable tc_ccnt : slbit := '0'; + variable tc_bcnt : slbit := '0'; + variable ld_dcnt : slbit := '0'; + variable ld_bcnt : slbit := '0'; + variable ce_bcnt : slbit := '0'; + variable iact : slbit := '0'; + variable ival : slbit := '0'; + variable ierr : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + dbit := '0'; + ld_ccnt := '0'; + tc_ccnt := '0'; + tc_bcnt := '0'; + ld_dcnt := '0'; + ld_bcnt := '0'; + ce_bcnt := '0'; + iact := '1'; + ival := '0'; + ierr := '0'; + + if unsigned(r.ccnt) = 0 then + tc_ccnt := '1'; + end if; + if unsigned(r.bcnt) = 9 then + tc_bcnt := '1'; + end if; + + if unsigned(r.dcnt) > unsigned("00" & CLKDIV(CDWIDTH-1 downto 1)) then + dbit := '1'; + end if; + + case r.state is + + when s_idle => -- s_idle: idle ---------------------- + iact := '0'; + ld_dcnt := '1'; -- always keep dcnt in reset + if RXSD = '0' then -- if start bit seen + if tc_ccnt = '1' then + n.state := s_endb0; -- finish b0 + ld_ccnt := '1'; -- start next bit + ce_bcnt := '1'; + else + n.state := s_colb0; -- collect b0 + end if; + else -- otherwise + ld_ccnt := '1'; -- keep all counters in reset + ld_bcnt := '1'; + end if; + + when s_colb0 => -- s_colb0: collect b0 (start bit) --- + if tc_ccnt = '1' then -- last cycle of b0 ? + n.state := s_endb0; -- finish b0 + ld_ccnt := '1'; -- " + ce_bcnt := '1'; + else -- continue in b0 ? + if dbit='1' and RXSD='1' then -- too many 1's ? + n.state := s_idle; -- abort to idle + ld_dcnt := '1'; -- put counters in reset + ld_ccnt := '1'; + ld_bcnt := '1'; + end if; + end if; + + when s_endb0 => -- s_endb0: finish b0 (start bit) --- + ld_dcnt := '1'; -- start next bit + if dbit = '1' then -- was it a 1 ? + n.state := s_idle; -- abort to idle + ld_ccnt := '1'; -- put counters in reset + ld_bcnt := '1'; + else + if tc_ccnt = '1' then -- last cycle of bx ? + n.state := s_endbx; -- finish bx + ld_ccnt := '1'; + ce_bcnt := '1'; + else -- continue in b0 ? + n.state := s_colbx; -- collect bx + end if; + end if; + + when s_colbx => -- s_colbx: collect bx --------------- + if tc_ccnt = '1' then -- last cycle of bx ? + n.state := s_endbx; -- finish bx + ld_ccnt := '1'; + ce_bcnt := '1'; + end if; + + when s_endbx => -- s_endbx: finish bx --------------- + ld_dcnt := '1'; -- start next bit + n.sreg := dbit & r.sreg(7 downto 1); + if tc_ccnt = '1' then -- last cycle of bx ? + if tc_bcnt = '1' then + n.state := s_endb9; -- finish b9 + ld_bcnt := '1'; -- and wrap bcnt + else + n.state := s_endbx; -- finish bx + ce_bcnt := '1'; + end if; + ld_ccnt := '1'; + else -- continue in bx ? + if tc_bcnt = '1' then + n.state := s_colb9; -- collect b9 + else + n.state := s_colbx; -- collect bx + end if; + end if; + + when s_colb9 => -- s_colb9: collect bx (stop bit) ---- + if tc_ccnt = '1' then -- last cycle of b9 ? + n.state := s_endb9; -- finish b9 + ld_ccnt := '1'; -- " + ld_bcnt := '1'; -- and wrap bcnt + else -- continue in b9 ? + if dbit='1' and RXSD='1' then -- already enough 1's ? + n.state := s_idle; -- finish to idle + ld_dcnt := '1'; -- put counters in reset + ld_ccnt := '1'; + ld_bcnt := '1'; + ival := '1'; + end if; + end if; + + when s_endb9 => -- s_endb9: finish bx (stop bit) ---- + ld_dcnt := '1'; -- start next bit + if dbit = '1' then -- was it a valid stop bit ? + ival := '1'; + else + ierr := '1'; + end if; + if RXSD = '1' then -- line in idle state ? + n.state := s_idle; -- finish to idle state + ld_ccnt := '1'; -- and put counters in reset + ld_bcnt := '1'; -- " + else + if tc_ccnt = '1' then -- last cycle of b9 ? + n.state := s_endb0; -- finish b0 + ld_ccnt := '1'; -- " + ce_bcnt := '1'; + else -- continue in b0 ? + n.state := s_colb0; -- collect bx + end if; + end if; + + when others => null; -- ----------------------------------- + + end case; + + if RESET = '1' then -- RESET seen + ld_ccnt := '1'; -- keep all counters in reset + ld_dcnt := '1'; + ld_bcnt := '1'; + n.state := s_idle; + end if; + + if ld_ccnt = '1' then -- implement ccnt + n.ccnt := CLKDIV; + else + n.ccnt := unsigned(r.ccnt) - 1; + end if; + + if ld_dcnt = '1' then -- implement dcnt + n.dcnt(CDWIDTH downto 1) := (others=>'0'); + n.dcnt(0) := RXSD; + else + if RXSD = '1' then + n.dcnt := unsigned(r.dcnt) + 1; + end if; + end if; + + if ld_bcnt = '1' then -- implement bcnt + n.bcnt := (others=>'0'); + else + if ce_bcnt = '1' then + n.bcnt := unsigned(r.bcnt) + 1; + end if; + end if; + + N_REGS <= n; + + RXDATA <= r.sreg; + RXACT <= iact; + RXVAL <= ival; + RXERR <= ierr; + + end process proc_next; + +end syn; Index: serport_uart_rxtx_ab.vbom =================================================================== --- serport_uart_rxtx_ab.vbom (nonexistent) +++ serport_uart_rxtx_ab.vbom (revision 7) @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +serport.vhd +# components +serport_uart_autobaud.vbom +serport_uart_rxtx.vbom +# design +serport_uart_rxtx_ab.vhd Index: serport_uart_rx.vbom =================================================================== --- serport_uart_rx.vbom (nonexistent) +++ serport_uart_rx.vbom (revision 7) @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +serport_uart_rx.vhd Index: serport_uart_tx.vhd =================================================================== --- serport_uart_tx.vhd (nonexistent) +++ serport_uart_tx.vhd (revision 7) @@ -0,0 +1,132 @@ +-- $Id: serport_uart_tx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_tx - syn +-- Description: serial port UART - transmitter +-- +-- Dependencies: - +-- Test bench: tb/tb_serport_uart_rxtx +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-21 91 1.0.3 use 1 stop bits (redesigned _rx allows this) +-- 2007-10-19 90 1.0.2 use 2 stop bits (allow CLKDIV=0 operation in sim) +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity serport_uart_tx is -- serial port uart: transmit part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end serport_uart_tx; + + +architecture syn of serport_uart_tx is + + type regs_type is record + ccnt : slv(CDWIDTH-1 downto 0); -- clock divider counter + bcnt : slv4; -- bit counter + sreg : slv9; -- output shift register + busy : slbit; + end record regs_type; + + constant cntzero : slv(CDWIDTH-1 downto 0) := (others=>'0'); + constant regs_init : regs_type := ( + cntzero, + (others=>'0'), + (others=>'1'), -- sreg to all 1 !! + '0' + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RESET, CLKDIV, TXDATA, TXENA) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ld_ccnt : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + ld_ccnt := '0'; + + if r.busy = '0' then + ld_ccnt := '1'; + n.bcnt := (others=>'0'); + if TXENA = '1' then + n.sreg := TXDATA & '0'; -- add start (0) bit + n.busy := '1'; + end if; + + else + + if unsigned(r.ccnt) = 0 then + ld_ccnt := '1'; + n.sreg := '1' & r.sreg(8 downto 1); + n.bcnt := unsigned(r.bcnt) + 1; + if unsigned(r.bcnt) = 9 then -- if 10 bits send + n.busy := '0'; -- declare all done + end if; + end if; + end if; + + if RESET = '1' then + ld_ccnt := '1'; + n.busy := '0'; + end if; + + if ld_ccnt = '1' then + n.ccnt := CLKDIV; + else + n.ccnt := unsigned(r.ccnt) - 1; + end if; + + N_REGS <= n; + + TXBUSY <= r.busy; + TXSD <= r.sreg(0); + + end process proc_next; + +end syn; Index: serport_uart_tx.vbom =================================================================== --- serport_uart_tx.vbom (nonexistent) +++ serport_uart_tx.vbom (revision 7) @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +serport_uart_tx.vhd Index: serport_uart_autobaud.vhd =================================================================== --- serport_uart_autobaud.vhd (nonexistent) +++ serport_uart_autobaud.vhd (revision 7) @@ -0,0 +1,173 @@ +-- $Id: serport_uart_autobaud.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_autobaud - syn +-- Description: serial port UART - autobauder +-- +-- Dependencies: - +-- Test bench: tb/tb_serport_autobaud +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-18 279 1.0.3 change ccnt start value to -3, better rounding +-- 2007-10-14 89 1.0.2 all instantiation with CDINIT=0 +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity serport_uart_autobaud is -- serial port uart: autobauder + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + CLKDIV : out slv(CDWIDTH-1 downto 0); -- clock divider setting + ACT : out slbit; -- active; if 1 clkdiv is invalid + DONE : out slbit -- resync done + ); +end serport_uart_autobaud; + + +architecture syn of serport_uart_autobaud is + + type state_type is ( + s_idle, + s_break, + s_wait, + s_sync + ); + + type regs_type is record + ccnt : slv(CDWIDTH-1+3 downto 0); -- clock divider counter + mcnt : slv7; -- msec counter + seen1 : slbit; -- seen a '1' in this msec + state : state_type; -- state + end record regs_type; + + -- Note on initialization of ccnt: + -- - in the current logic ccnt is incremented n-1 times when n is number + -- clock cycles with a RXD of '0'. When running at 50 MBaud, ccnt will + -- be incremented 7 (not 8!) times. + -- - the three LSBs of ccnt should be at 100 under perfect conditions, this + -- gives the best rounded estimate of CLKDIV. + -- - therefore ccnt is inititialized with 111111.101: 101 + 111 -> 1100 + -- --> ccntinit = -3 + + constant ccntinit : slv(CDWIDTH-1+3 downto 0) := + conv_std_logic_vector(2**(CDWIDTH+3)-3, CDWIDTH+3); + constant mcntzero : slv7 := (others=>'0'); + constant mcntlast : slv7 := (others=>'1'); + constant regs_init : regs_type := ( + conv_std_logic_vector(CDINIT,CDWIDTH)&"000", + (others=>'0'), + '0', + s_idle + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert CDINIT <= 2**CDWIDTH-1 + report "assert(CDINIT <= 2**CDWIDTH-1): CDINIT too large for given CDWIDTH" + severity FAILURE; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, CE_MSEC, RESET, RXSD) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable iact : slbit := '0'; + variable idone : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + iact := '1'; + idone := '0'; + + case r.state is + when s_idle => -- s_idle: idle, detect break -------- + iact := '0'; + if CE_MSEC = '1' then -- if end of msec + if r.seen1 = '0' then -- if no '1' seen on RXD + n.mcnt := unsigned(r.mcnt) + 1; -- up break timer counter + if r.mcnt = mcntlast then -- after 127 msec + n.state := s_break; -- break detected ! + end if; + else -- otherwise if '1' seen + n.mcnt := mcntzero; -- clear break timer again + end if; + n.seen1 := RXSD; -- latch current RXD value + else -- otherwise if not at end-of-msec + n.seen1 := r.seen1 or RXSD; -- remember whether RXS=1 seen + end if; + + when s_break => -- s_break: detect end of break ------ + if RXSD = '1' then -- if end of break seen + n.state := s_wait; -- to s_wait to wait for sync char + n.ccnt := ccntinit; -- and initialize ccnt + end if; -- otherwise stay in s_break + + when s_wait => -- s_wait: wait for sync char -------- + if RXSD = '0' then -- if start bit if sync char seen + n.state := s_sync; -- to s_sync to wait for end of '0' + end if; -- otherwise stay in s_wait + + when s_sync => -- s_sync: wait for end of '0' bits -- + if RXSD = '1' then -- if end of '0' bits seen + n.state := s_idle; -- to s_idle, autobauding done + idone := '1'; -- emit done pulse + else -- otherwise still in '0' of sync + n.ccnt := unsigned(n.ccnt) + 1; -- increment ccnt + end if; + + when others => null; -- ----------------------------------- + end case; + + N_REGS <= n; + + CLKDIV <= r.ccnt(CDWIDTH-1+3 downto 3); + ACT <= iact or RESET; + DONE <= idone; + + end process proc_next; + +end syn; Index: Makefile =================================================================== --- Makefile (nonexistent) +++ Makefile (revision 7) @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.0.1 drop ISE_p definition +# 2007-07-03 45 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# Index: serport.vhd =================================================================== --- serport.vhd (nonexistent) +++ serport.vhd (revision 7) @@ -0,0 +1,134 @@ +-- $Id: serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: serport +-- Description: serial port interface components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-10 276 1.2 add clock divider constant defs +-- 2007-10-22 88 1.1 renames (in prev revs); remove std_logic_unsigned +-- 2007-06-03 45 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package serport is + +-- clock divider constants assume 50 MHz clock + + constant serport_clkdiv_009600 : integer := 5208-1; -- 50000000/ 9600=5208.33 + constant serport_clkdiv_019200 : integer := 2604-1; -- 50000000/ 19200=2604.16 + constant serport_clkdiv_038400 : integer := 1302-1; -- 50000000/ 38400=1302.08 + constant serport_clkdiv_057600 : integer := 868-1; -- 50000000/ 57600= 868.05 + constant serport_clkdiv_115200 : integer := 434-1; -- 50000000/115200= 434.02 + constant serport_clkdiv_230400 : integer := 217-1; -- 50000000/230400= 217.01 + constant serport_clkdiv_460800 : integer := 109-1; -- 50000000/460800= 108.51 + constant serport_clkdiv_500000 : integer := 100-1; -- 50000000/500000= 100 + constant serport_clkdiv_576000 : integer := 87-1; -- 50000000/576000= 86.80 + constant serport_clkdiv_921600 : integer := 54-1; -- 50000000/921600= 54.25 + constant serport_clkdiv_1M : integer := 50-1; -- 50000000/1M = 50 + constant serport_clkdiv_2M : integer := 24-1; -- 50000000/2M = 25 + +component serport_uart_rxtx is -- serial port uart: rx+tx combo + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end component; + +component serport_uart_rx is -- serial port uart: receive part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit -- receiver active + ); +end component; + +component serport_uart_tx is -- serial port uart: transmit part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end component; + +component serport_uart_rxtx_ab is -- serial port uart: rx+tx+autobaud + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit; -- transmit busy + ABACT : out slbit; -- autobaud active; if 1 clkdiv invalid + ABDONE : out slbit -- autobaud resync done + ); +end component; + +component serport_uart_autobaud is -- serial port uart: autobauder + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + CLKDIV : out slv(CDWIDTH-1 downto 0); -- clock divider setting + ACT : out slbit; -- active; if 1 clkdiv is invalid + DONE : out slbit -- resync done + ); +end component; + +end serport; Index: serport_uart_rxtx.vhd =================================================================== --- serport_uart_rxtx.vhd (nonexistent) +++ serport_uart_rxtx.vhd (revision 7) @@ -0,0 +1,85 @@ +-- $Id: serport_uart_rxtx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_rxtx - syn +-- Description: serial port UART - transmitter + receiver +-- +-- Dependencies: serport_uart_rx +-- serport_uart_tx +-- Test bench: tb/tb_serport_uart_rxtx +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.serport.all; + +entity serport_uart_rxtx is -- serial port uart: rx+tx combo + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end serport_uart_rxtx; + +architecture syn of serport_uart_rxtx is + +begin + + RX : serport_uart_rx + generic map ( + CDWIDTH => CDWIDTH) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT + ); + + TX : serport_uart_tx + generic map ( + CDWIDTH => CDWIDTH) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + +end syn; Index: . =================================================================== --- . (nonexistent) +++ . (revision 7)
. Property changes : Added: svn:ignore ## -0,0 +1,32 ## +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.