This is a multi-part message in MIME format.
--------------070302010109050402040109
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
> I wonder if there is any simple way to send the data from a block-ram to
> the RS232-interface, without the need to write all the RS232 VHDL-code
> myself!
There you go. And can we now stop requesting RS232 stuff? ;)
Jan
--------------070302010109050402040109
Content-Type: text/plain;
name="EIA232_TX_bridge.vhd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="EIA232_TX_bridge.vhd"
--
-- ***Author***
-- Jan De Ceuster
--
-- *** File ***
-- EIA232_TX_bridge.vhd
--
-- *** Entity ***
-- EIA232_TX_bridge
--
-- *** Port list ***
-- nrst (in, 1) Active low reset
-- clk (in, 1) System Clock
--
-- EIA232_TXD (in, 1) EIA232 Receive Serial Data from PC
-- EIA232_CTS (out, 1) EIA232 Stop Receiving
--
-- ParallelIN_Data (out, 8) ParallelIN sends the data from EIA232 interface.
-- ParallelIN_Ack (out, 1) protocol: synchronous Full Handshake, device
-- ParallelIN_Req (in, 1) is slave.
library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all;
library work;
use work.shift_registers.all;
use work.EIA232.all;
entity EIA232_TX_bridge is
generic (
DATASIZE : in integer := 8;
CLKFREQ : in integer := 33000000; -- clock frequency in Hz
BAUDRATE : in integer := 115200
);
port (
nrst : in std_logic;
clk : in std_logic;
EIA232_TXD : in std_logic;
EIA232_CTS : out std_logic;
ParallelIN_Data : out std_logic_vector(DATASIZE-1 downto 0);
ParallelIN_Req : in std_logic;
ParallelIN_Ack : out std_logic
);
end EIA232_TX_bridge;
architecture RTL of EIA232_TX_bridge is
constant BITCOUNTER_SIZE : integer := DATASIZE - 1;
constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1;
constant HALF_TIMECOUNTER_SIZE : integer := TIMECOUNTER_SIZE/2 - 1;
signal timecounter : integer range 0 to TIMECOUNTER_SIZE;
signal bitcounter : integer range 0 to DATASIZE-1;
signal ParallelIN_Data_reg : std_logic_vector(1 to DATASIZE);
signal EIA232State, nextEIA232State : EIA232State_type;
signal timecounter_pulse : std_logic;
signal StartReceive : std_logic;
signal sync_EIA232_TXD : std_logic_vector(2 downto 1);
signal faling_edge_EIA232_TXD : boolean;
signal buffer_empty : boolean;
begin
process (EIA232State, StartReceive, bitcounter)
begin
nextEIA232State <= EIA232State;
case EIA232State is
when E_EIA232State_Waiting =>
if StartReceive = '1' then
nextEIA232State <= E_EIA232State_Start;
end if;
when E_EIA232State_Start =>
nextEIA232State <= E_EIA232State_Data;
when E_EIA232State_Data =>
if bitcounter = 0 then
nextEIA232State <= E_EIA232State_Stop;
end if;
when E_EIA232State_Stop =>
nextEIA232State <= E_EIA232State_Waiting;
when others =>
end case;
end process;
-- sample signal into flipflops
process (clk)
begin
if rising_edge(clk) then
ShiftL2H(EIA232_TXD,sync_EIA232_TXD);
end if;
end process;
faling_edge_EIA232_TXD <= sync_EIA232_TXD(sync_EIA232_TXD'high-1) = '0'
and sync_EIA232_TXD(sync_EIA232_TXD'high) = '1';
timecounter_pulse <= '1' when timecounter = 0 else '0';
process (clk, nrst)
begin
if nrst = '0' then
timecounter <= TIMECOUNTER_SIZE;
StartReceive <= '0';
elsif rising_edge(clk) then
-- endless timer with conditional preload (when detecting a startbit)
-- StartReceive indicates the detection of the startbit
if faling_edge_EIA232_TXD -- faling edge TXD,
and nextEIA232State = E_EIA232State_Waiting then -- detect start bit
timecounter <= HALF_TIMECOUNTER_SIZE;
StartReceive <= '1';
elsif timecounter = 0 then -- counter reset
timecounter <= TIMECOUNTER_SIZE;
StartReceive <= '0';
else
timecounter <= timecounter - 1; -- count down
end if;
end if;
end process;
process (clk, nrst)
begin
if nrst = '0' then
EIA232State <= E_EIA232State_Waiting;
ParallelIN_Data_reg <= (others => '-');
bitcounter <= BITCOUNTER_SIZE;
elsif rising_edge(clk) then
if timecounter_pulse = '1' then
EIA232State <= nextEIA232State;
bitcounter <= BITCOUNTER_SIZE;
-- shift register
ShiftL2H(sync_EIA232_TXD(sync_EIA232_TXD'high),ParallelIN_Data_reg);
if EIA232State = E_EIA232State_Start
or EIA232State = E_EIA232State_Data then
-- counter for the shiftregister
if bitcounter = 0 then
bitcounter <= BITCOUNTER_SIZE;
else
bitcounter <= bitcounter - 1;
end if;
end if;
end if;
end if;
end process;
process (clk, nrst)
begin
if nrst = '0' then
buffer_empty <= TRUE;
EIA232_CTS <= '1';
ParallelIN_Ack <= '0';
elsif rising_edge(clk) then
if buffer_empty then
EIA232_CTS <= '0';
else
EIA232_CTS <= '1';
end if;
if EIA232State = E_EIA232State_Data then
buffer_empty <= FALSE;
end if;
-- Output the shiftregister directly.
if timecounter_pulse = '1' and EIA232State = E_EIA232State_Stop then
ParallelIN_Data <= ParallelIN_Data_reg;
end if;
-- The shiftregister now contains the received byte.
-- => give an ack for 1 clock cycle (done with timecounter_pulse)
if ParallelIN_REQ = '1' and not buffer_empty and EIA232State = E_EIA232State_Waiting then
ParallelIN_Ack <= '1';
buffer_empty <= TRUE;
else
ParallelIN_Ack <= '0';
end if;
end if;
end process;
end RTL;
--------------070302010109050402040109
Content-Type: text/plain;
name="EIA232_package.vhd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="EIA232_package.vhd"
--
-- ***Author***
-- Jan De Ceuster
--
-- *** File ***
-- EIA232_constants.vhd
--
-- *** Entity ***
--
-- *** Port list ***
--
-- *** Description ***
--
-- *** History ***
--
library ieee;
use ieee.std_logic_1164.all;
package EIA232 is
-- enumerations
type EIA232State_type is (E_EIA232State_Waiting, E_EIA232State_Start,
E_EIA232State_Data, E_EIA232State_Stop);
-- constants
-- functions
-- procedures
-- components
component EIA232_TX_bridge
-- receive data via a FullHndshk protocol
-- bridge is master on EIA232 lines
generic (
DATASIZE : in integer := 8; -- size can be anything from 5 to 8
CLKFREQ : in integer := 33000000; -- clock frequency in Hz
BAUDRATE : in integer := 115200
);
port (
nrst : in std_logic;
clk : in std_logic;
EIA232_TXD : in std_logic;
EIA232_CTS : out std_logic;
ParallelIN_Data : out std_logic_vector(DATASIZE-1 downto 0);
ParallelIN_Req : in std_logic;
ParallelIN_Ack : out std_logic
);
end component;
component EIA232_RX_bridge
-- send data via a FullHndshk protocol
-- bridge is master on EIA232 lines
generic (
DATASIZE : in integer := 8; -- size can be anything from 5 to 8
CLKFREQ : in integer := 33000000; -- clock frequency in Hz
BAUDRATE : in integer := 115200
);
port (
nrst : in std_logic;
clk : in std_logic;
EIA232_RXD : out std_logic;
EIA232_RTS : in std_logic;
ParallelOUT_Data : in std_logic_vector(DATASIZE-1 downto 0);
ParallelOUT_Req : in std_logic;
ParallelOUT_Ack : out std_logic
);
end component;
component EIA232_ASCIIfileio
-- model using files to send and get ASCII data to/from the system.
generic (
DATASIZE : in integer := 8; -- size can be anything from 5 to 8
CLKFREQ : in integer := 33000000; -- clock frequency in Hz
BAUDRATE : in integer := 115200;
READFILE : string := "";
WRITEFILE : string := ""
);
port (
nrst : in std_logic;
clk : in std_logic;
EIA232_RXD : in std_logic;
EIA232_RTS : out std_logic;
EIA232_TXD : out std_logic;
EIA232_CTS : in std_logic;
done : out boolean := false
);
end component;
end EIA232;
package body EIA232 is
end EIA232;
--------------070302010109050402040109
Content-Type: text/plain;
name="EIA232_RX_bridge.vhd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="EIA232_RX_bridge.vhd"
--
-- ***Author***
-- Jan De Ceuster
--
-- *** File ***
-- EIA232_RX_bridge.vhd
--
-- *** Entity ***
-- EIA232_RX_bridge
--
-- *** Port list ***
-- nrst (in, 1) Active low reset
-- clk (in, 1) System Clock
--
-- EIA232_RXD (out, 1) EIA232 Transmit Serial Data to PC
-- EIA232_RTS (in, 1) EIA232 Stop Sending
--
-- ParallelOUT_Data (in, 8) ParallelOUT sends the data to EIA232 interface.
-- ParallelOUT_Ack (out, 1) protocol: synchronous Full Handshake, device is slave
-- ParallelOUT_Req (in, 1)
--
-- *** Description ***
-- This block will translate the parallel data from a generic interface to
-- a serial output according the EIA232 standard with RXD and RTS.
-- The size of the parallel data (generic paramter DATASIZE) can be anything
-- from 5 to 8. This is also as specified in the EIA232 standard.
-- One start and stopbit is provided.
-- The generic parameter CLK_DIV is used to set the correct baudrate:
-- baudrate = inputfreq/CLK_DIV
--
-- *** History ***
-- 001 27-06-2003 Initial version
-- Fully tested and optimized
library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all;
library work;
use work.shift_registers.all;
use work.EIA232.all;
entity EIA232_RX_bridge is
generic (
DATASIZE : in integer := 8; -- size can be anything from 5 to 8
CLKFREQ : in integer := 33000000; -- clock frequency in Hz
BAUDRATE : in integer := 115200
);
port (
nrst : in std_logic;
clk : in std_logic;
EIA232_RXD : out std_logic;
EIA232_RTS : in std_logic;
ParallelOUT_Data : in std_logic_vector(DATASIZE-1 downto 0);
ParallelOUT_Req : in std_logic;
ParallelOUT_Ack : out std_logic
);
end EIA232_RX_bridge;
architecture RTL of EIA232_RX_bridge is
constant TIMECOUNTER_SIZE : integer := integer(real(CLKFREQ/BAUDRATE)-1.0);
signal timecounter : integer range 0 to TIMECOUNTER_SIZE;
signal bitcounter : integer range 0 to DATASIZE;
signal EIA232ShiftRegister : std_logic_vector(1 to DATASIZE);
signal EIA232State, nextEIA232State : EIA232State_type;
signal StartSending : std_logic;
signal timecounter_pulse : std_logic;
signal sync_EIA232_RTS : std_logic_vector(3 downto 1);
begin
-- The EIA232State statemachine controls the correct flow for the start, data
-- and stop bit(s).
process (EIA232State, StartSending, bitcounter)
begin
nextEIA232State <= EIA232State;
case EIA232State is
when E_EIA232State_Waiting =>
-- Req for sending data received.
if StartSending = '1' then
nextEIA232State <= E_EIA232State_Start;
end if;
when E_EIA232State_Start =>
nextEIA232State <= E_EIA232State_Data;
when E_EIA232State_Data =>
-- Last databit send.
if bitcounter = DATASIZE and StartSending = '0' then
nextEIA232State <= E_EIA232State_Waiting;
end if;
when others =>
end case;
end process;
-- Generate a pulse when timecounter is 0.
timecounter_pulse <= '1' when timecounter = 0 else '0';
-- Sample the inputsignal from physical EIA232 interface into a flipflop.
process (clk)
begin
if rising_edge(clk) then
ShiftL2H(EIA232_RTS,sync_EIA232_RTS);
end if;
end process;
process (clk,nrst)
begin
if nrst = '0' then
timecounter <= TIMECOUNTER_SIZE;
ParallelOUT_Ack <= '0';
StartSending <= '0';
EIA232ShiftRegister <= (others => '1');
elsif rising_edge(clk) then
ParallelOUT_Ack <= '0';
-- Counter to devide the clk input.
if timecounter_pulse = '1' then
timecounter <= TIMECOUNTER_SIZE;
else
timecounter <= timecounter - 1;
end if;
case EIA232State is
when E_EIA232State_Waiting =>
-- Req received and ready to transmit data.
if StartSending = '0' and ParallelOUT_Req = '1'
and sync_EIA232_RTS(sync_EIA232_RTS'high) = '0' then
-- Load the shiftregister
EIA232ShiftRegister(1 to DATASIZE) <= ParallelOUT_Data;
ParallelOUT_Ack <= '1';
StartSending <= '1';
end if;
when E_EIA232State_Start | E_EIA232State_Data =>
StartSending <= '0';
-- The shiftregister can shift every timecounter_pulse.
-- This register runs on clk because it must be possible to load
-- external data assynchronous to timecounter_pulse.
if timecounter_pulse = '1' then
ShiftL2H('1',EIA232ShiftRegister);
end if;
when others =>
StartSending <= '0';
end case;
end if;
end process;
process (clk,nrst)
begin
if nrst = '0' then
EIA232_RXD <= '1';
EIA232State <= E_EIA232State_Waiting;
bitcounter <= 0;
elsif rising_edge(clk) then
if timecounter_pulse = '1' then
EIA232State <= nextEIA232State;
case nextEIA232State is
when E_EIA232State_Waiting =>
EIA232_RXD <= '1';
when E_EIA232State_Start =>
EIA232_RXD <= '0';
when E_EIA232State_Data =>
EIA232_RXD <= EIA232ShiftRegister(DATASIZE);
if bitcounter = DATASIZE then
bitcounter <= 0;
else
bitcounter <= bitcounter + 1;
end if;
when others =>
end case;
end if;
end if;
end process;
end RTL;
--------------070302010109050402040109
Content-Type: text/plain;
name="EIA232_ASCIIfileIO.vhd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="EIA232_ASCIIfileIO.vhd"
--
-- ***Author***
--
-- *** File ***
-- EIA232_fileio.vhd
--
-- *** Entity ***
-- EIA232_fileio
--
-- *** Port list ***
--
-- *** Description ***
--
-- *** History ***
-- 001
library std;
use std.textio.all;
library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all;
library nicethings;
use nicethings.ASCII.all, nicethings.overloaded_std_logic_arith.all;
library communication;
use communication.EIA232.all;
entity EIA232_ASCIIfileio is
generic (
DATASIZE : in integer := 8; -- size can be anything from 5 to 8
CLKFREQ : in integer := 33000000; -- clock frequency in Hz
BAUDRATE : in integer := 115200;
READFILE : string := "";
WRITEFILE : string := ""
);
port (
nrst : in std_logic;
clk : in std_logic;
EIA232_RXD : in std_logic;
EIA232_RTS : out std_logic;
EIA232_TXD : out std_logic;
EIA232_CTS : in std_logic;
done : out boolean := FALSE
);
end EIA232_ASCIIfileio;
architecture model of EIA232_ASCIIfileio is
--signals of the EIA232 side
signal in_Data : std_logic_vector(DATASIZE-1 downto 0);
signal in_REQ, in_ACK : std_logic;
signal out_Data : std_logic_vector(DATASIZE-1 downto 0);
signal out_REQ, out_ACK : std_logic;
signal RXstate : integer := 0;
signal TXstate : integer := 0;
begin
TX_test : EIA232_TX_bridge
generic map (DATASIZE,CLKFREQ,BAUDRATE)
port map (nrst=>nrst,clk=>clk,
EIA232_TXD=>EIA232_RXD,EIA232_CTS=>EIA232_RTS,
ParallelIN_Data=>in_Data,ParallelIN_Req=>in_REQ,
ParallelIN_Ack=>in_ACK);
RX_test : EIA232_RX_bridge
generic map (DATASIZE,CLKFREQ,BAUDRATE)
port map (nrst=>nrst,clk=>clk,
EIA232_RXD=>EIA232_TXD,EIA232_RTS=>EIA232_CTS,
ParallelOUT_Data=>out_Data,ParallelOUT_Req=>out_REQ,
ParallelOUT_Ack=>out_ACK);
RX_SIDE : if READFILE /= "" generate
-- EIA232 RX side
process (clk, nrst)
file Fread : TEXT open READ_MODE is READFILE;
variable L : line;
variable char : character;
begin
if nrst = '0' then
out_REQ <= '0';
out_Data <= (others => '0');
RXstate <= 0;
done <= FALSE;
elsif rising_edge(clk) then
case RXstate is
when 0 =>
readline(Fread,L);
RXstate <= 1;
when 1 =>
if L'length = 0 then
char := LF;
else
read(L,char);
end if;
out_REQ <= '1';
out_Data <= conv_std_logic_vector(char,DATASIZE-1);
RXstate <= 2;
when 2 =>
if out_ACK = '1' then
out_REQ <= '0';
if char = LF then
if endfile(Fread) then
RXstate <= 3;
else
readline(Fread,L);
RXstate <= 1;
end if;
else
RXstate <= 1;
end if;
end if;
when others =>
done <= TRUE;
end case;
end if;
end process;
end generate;
TX_SIDE : if WRITEFILE /= "" generate
-- EIA232 TX side
process (clk, nrst)
file Fwrite : TEXT open WRITE_MODE is WRITEFILE;
variable L : line;
variable char : character;
begin
if nrst = '0' then
in_REQ <= '0';
TXstate <= 0;
elsif rising_edge(clk) then
case TXstate is
when 0 =>
in_REQ <= '1';
TXstate <= 1;
when 1 =>
if in_ACK = '1' then
in_REQ <= '0';
TXstate <= 0;
if in_DATA /= C_ASCII_LF then
write(L,conv_character(in_DATA));
else
writeline(Fwrite,L);
end if;
end if;
when others =>
end case;
end if;
end process;
end generate;
end model;
--------------070302010109050402040109--