I am working on a project where I send serial data from my PC to an FPGA
which samples it, captures it and puts it in an external memory.
In order to test this using a test bench, I need a model for the RS 232
transmitter - a model that mimics sending 8 bits of RS 232 data at 9600
Hz. I got the model of the memory from the vendor.Where can I get a model
of the RS 232 to use for my test bench?
Bert has given you a link to a synthesisable UART IP block, but for
a test bench it is really very simple. Just write a procedure, and
put the procedure in a package. Code below. It's left as a trivial
exercise for the student to add parity, variable numbers of stop
bits, and suchlike extra goodies. Make sure you know what you're
doing about the line signal levels - I've assumed the line marks
at '1' and spaces at '0', which is usually correct in the core
logic, but the RS-232 line discipline uses negative voltage for
marking and positive for spacing. The line transceiver chips
do the necessary level shifting and inversion for you, so you
don't normally need to worry about it in the FPGA.
It is somewhat trickier to write a behavioural model of a
UART receiver, but even that isn't too mind-bending.
Enjoy writing and using behavioural models!
Take my package here and use it as you see fit - I've
checked that it works, but as usual on Usenet you get
no commercial guarantee of reliability or fitness for
purpose. The little entity/architecture at the end is
a very quick demonstration of how to use the package.
------------------------------------------------------ package ---
library IEEE;
use IEEE.std_logic_1164.all;
package UART_behavioural_model is
procedure UART_tx (
-- The signal that is to be driven by this model...
signal tx_line: out std_logic;
-- Inputs to control how to send one character:
data: in std_logic_vector; -- usually 8 bits
baud_rate:in integer -- e.g. 9600
);
end package UART_behavioural_model;
--------------------------------------------------- package body ---
package body UART_behavioural_model is
procedure UART_tx (
-- The signal that is to be driven by this model...
signal tx_line: out std_logic;
-- Inputs to control how to send one character:
data: in std_logic_vector; -- usually 8 bits
baud_rate:in integer -- e.g. 9600
) is
constant bit_time: time := 1 sec / baud_rate;
begin
-- Send the start bit
tx_line <= '0';
wait for bit_time;
-- Send the data bits, least significant first
for i in data'reverse_range loop
tx_line <= data(i);
wait for bit_time;
end loop;
-- Send the stop bit
tx_line <= '1';
wait for bit_time;
end; -- procedure UART_tx
end package body UART_behavioural_model;
---------------------------------------------- a simple test ---
library IEEE;
use IEEE.std_logic_1164.all;
-- Import our UART tester package
use work.UART_behavioural_model.all;
entity try_the_UART is end;
architecture A of try_the_UART is
-- A signal for the tester to drive, initialised to "marking"
signal serial_line: std_logic := '1';
begin
Testing: process
constant My_Baud_Rate: integer := 9600;
-- Make a jacket procedure around UART_tx, for convenience
procedure send (data: in std_logic_vector) is
begin
UART_tx(
tx_line => serial_line,
data => data,
baud_rate => My_Baud_Rate
);
end;
variable D: std_logic_vector(7 downto 0);
begin
-- Idle awhile
wait for 1 ms;
-- Send an 8-bit character as a test
send("10001110");
-- Idle some more
wait for 1 ms;
-- Some more characters - use a walking-ones pattern:
for i in D'range loop
D := (others => '0');
D(i) := '1';
send(D);
end loop;
-- And finally, just for fun, send a 10-bit character:
send("1111100000");
wait; -- That's All Folks
end process;
end;
--
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services
Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:
[email protected]
Fax: +44 (0)1425 471573 Web:
http://www.doulos.com
The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.