Task:
Redesign previous RS232 project in the following way:
The system should buffer data received from the RS232 port. After the
number of characters ‘row_max’ has been collected the system should print them
back to the RS-232 port in pseudo-graphic form (using the printed character as
a pixel).
Besides, the system should buffer input characters coming from the RS232
port in the printout phase. The length of the buffer should be 64 characters.
Buffer overflow should be signaled by LD0 LED (the LED should illuminate during
overflow condition). The RS232 port parameters should be identical to those
used in the previous exercise, also the RS232 port monitoring function (using
the LED display) should remain intact.
‘row_max’ parameter should be easily modifiable (for example defined as
a constant) and should accept values from 2 to 15.
The sample printout of several lines is presented below (row_max=8):
bbb ddd
fff hhh
bb dd ff ff hh
bb dd
ff f hh
aaaa
bbbbb cccc dddd
eeee ff ggg gg hh
aa
bb bb cc cc dd dd
ee ee fffff gg gg
hhhhh
aaaaa
bb bb cc dd dd
eeeeee ff gg
gg hh hh
aa aa
bb bb cc dd dd
ee ff gg
gg hh hh
aa aa
bbb bb cc cc
dd dd ee ee ff
ggggg hh hh
aaa aa bbb bb cccc ddd dd eeee
ffff gg hhh hh
gg gg
gggg
AA
BBBBBB CCC DDDDD
EEEEEE FFFFFF GGGG
HH HH
AAAA
BB BB CC CC DD DD EE
E FF F GGG GG HH
HH
AA
AA BB BB CC C
DD DD EE FF GG
HH HH
AA
AA BB BB CC DD
DD EE E FF F
GG HH HH
AA
AA BBBBB CC
DD DD EEEE FFFF GG
HHHHHH
AAAAAA
BB BB CC DD DD
EE E FF F GG GGG
HH HH
AA
AA BB BB CC C
DD DD EE FF GG
GG HH HH
AA
AA BB BB CC CC DD DD
EE E FF GGG GG HH
HH
AA AA
BBBBBB CCC DDDDD EEEEEE FFFF
GGGG HH HH
11
2222 3333 44
555555 666 777777
8888
111
22 22 33 33 444
55 66 77 77
88 88
1111
22 33 4444
55 66 77
88 88
11
22 33 44 44
55 66 77
88 88
11
22 3333 44
44 55555 66666
77 8888
11
22 33 4444444 55
66 66 77 88 88
11
22 33 44
55 66 66 77 88
88
11
22 22 33 33 44
55 55 66 66 77
88 88
1111
222222 3333 4444
5555 6666 77
8888
The characters which codes are below 32 or greater than 126 should be
printed using asterisks (*) as pixels. Do not implement control functions of
those characters (like Line Feed, Carriage Return, etc.). The example of a line
containing characters which codes are below 32 is presented below:
****
**** ***** *****
***** ***
*
* ** ** *** * * ******* ** ** * *****
****
** ** ** * * * * * ** * ** *******
*** *****
*
** ** ** * * * ******* ******* *****
***
* **** ****
* * ******* ******* *******
*******
*
** ** ** *
*** * ** ** ******* *****
*******
**
****** ** **
* * * *** *** ***** ***
*****
*** **
** ** * * ******* ***
* *
** ** **** *****
***** * *****
Ports’ usage:
For the project implementation two functional modules generated by the
Core Generator application will be needed. The ROM (Read Only Memory) will
provide characters’ fonts. The FIFO memory will be used as a 64-character input
buffer. The character definitions (8x16) can be downloaded here: chargen.coe
ROM module generation:
Choose:
Project -> New Source
This
will open a new window Select Source Type in which choose:
IP (CORE Generator & Architecture Wizard).
Enter the the file name of a new component (generated by Core Generator), for
example: char_mem and click Next:
The
window ”Select IP” for new component choice will be opened:
In this
window choose Block Memory Generator v2.8 and click Next. The
summary window will show up: New Source Wizard – Summary. It must be
acknowledged by clicking Finish.
Next
the Core Generator starts and the new window for component configuration is
opened:
In this
window (1/4) change Memory Type to Single Port ROM.
You can use View Data Sheet button (in the down left corner) to open
detailed documentation of the configured component.
Then
click Next.
In this
window (2/4) change Read Width to 8 (characters are defined with
a resolution of 8 pixels in the horizontal direction) and Read Depth to 4096 (there are 256 characters defined, and
each occupy 16 bytes in the memory).
Then
click Next.
In this
window (3/4) mark Load Init File and enter the path to the file chargen.coe with characters’ definitions (you can make
this quickly by using the Browse button).
Then
click Next.
In this
window (4/4) nothing should be changed. But, it is worth to remember helpful
project summary information (Information field) and the block symbol of
the designed component. The most important information is: Total Port A Read
Latency (From Rising Edge of Read Clock): 1 Clock Cycle(s)
Acknowledge
by pressing the Finish button.
The
component generation will begin – please wait a moment.
After
successful generation the component will be added to the list of project files.
Below the
definition of a character in the generated ROM is presented: (using the letter
R as an example):
Address |
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
ascii*16+0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
ascii*16+1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
ascii*16+2 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
ascii*16+3 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
ascii*16+4 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
ascii*16+5 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
ascii*16+6 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
ascii*16+7 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
ascii*16+8 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
ascii*16+9 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
ascii*16+10 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
ascii*16+11 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
ascii*16+12 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
ascii*16+13 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
ascii*16+14 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
ascii*16+15 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Address –
the address in the ROM.
ascii –
the ASCII code of a printed character.
The
address for the ROM can be easily generated by concatenating the 8-bit vector
of ASCII code with the 4-bit vector of line number of character (0-15) using
the & operator. Remember that after printing the line you should send two
control characters: CR (code: 13) and LF (code: 10) to make the cursor go to
the new line.
For
easy component instantiation files with *.vho extension are created. They
contain the template of component declaration and the example of how to make
the instance of the component. You can easily include those files in the
project files.
A
sample VHO file:
-- The following code must
appear in the VHDL architecture header:
------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG
component char_mem
port (
clka: IN std_logic;
addra: IN std_logic_VECTOR(11
downto 0);
douta: OUT std_logic_VECTOR(7
downto 0));
end component;
-- Synplicity black box declaration
attribute syn_black_box : boolean;
attribute syn_black_box of char_mem: component is true;
-- COMP_TAG_END ------ End COMPONENT Declaration ------------
-- The following code must appear in the VHDL architecture
-- body. Substitute your own instance name and net names.
------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG
your_instance_name : char_mem
port map (
clka => clka,
addra => addra,
douta => douta);
-- INST_TAG_END ------ End INSTANTIATION Template ------------
-- You must compile the wrapper file char_mem.vhd when simulating
-- the core, char_mem. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
The
text in red font should be copied to the local
signal definition area. The text in blue font
should be copied to the architecture area (of course the connected signals’
names and the instance name should be changed as needed). Then the icon
representing the new component should be automatically moved to the proper
place in the project’s hierarchy.
Modification
of component’s parameters and its regeneration is possible using the icons: Manage
Cores i Regenerate Core
presented below:
Generation of FIFO memory module:
To
generate the FIFO module proceed as follows:
Choose: Project -> New Source
In the
window Select Source Type choose: IP (CORE Generator & Architecture
Wizard).
Enter the file name for a new component, for example: fifo_mem and click Next:
Next
window will be opened - Select IP:
In this
window choose Fifo Generator v4.4 and click
Next.
Then the summary window appears: New Source Wizard – Summary.
You should acknowledge by pressing Finish.
Then
the Core Generator starts and the component configuration widow is opened:
In this
window (1/6) choose option: Common Clock (CLK) – Block RAM.
Use View Data Sheet button to see the complete and detailed
documentation of the core.
Then
click Next.
In this
window (2/6) change Write Width to 8, Write Depth to 64
(assumed FIFO capacity) and Read
Width to 8.
Please notice the information on the bottom of the page (it is generated based
on the options previously set and is important for FIFO reads):
Read Latency (From Rising Edge of Read Clock): 1
Then
click Next four times (leave the options of the next 4 windows
unchanged). Last window (6/6) should be printed like below:
It is
worth to remember the helpful summary of the properties of the designed
component (field Information).
Confirm
it by pressing Finish.
The
component generation procedure starts – please wait a moment.
Now you
have to instantiate the component in your project using *.vho file (the
procedure is similar to the one described for the previous ROM component).
Important
information about the FIFO component can also be found in UG175
document.
The circuit has to be
verified experimentally by programming the FPGA on the prototype board. You can
also perform functional simulation if you need. After the FPGA is programmed
check the basic functionality of the system: print some lines on the terminal
and check the buffer overflow detection (by keeping any key pressed for about 30
seconds). For testing use MINICOM
terminal emulation program (MINICOM is by default configured as follows:
9600bps, 8 data bits, 1 stop bit, no parity). Show the results to the
instructor.
Transmission and reception of data
in the RS232 standard:
Transmission and reception of data in the RS232 standard is done in a serial
manner, separately on two data lines (one data line for direction to the device
and one data line for direction from the device). When no transmission is
present, the signal on the line is high (logic level ‘1’). The start of the
transmission is initiated by the falling edge of the input signal followed by
the so-called ‘start bit’ (logic level ‘0’), which should last for a period
equal to the reciprocal of the baud rate, in our case 1/9600 [seconds]. All
subsequent bits are sent with the same timing. The data is transmitted in
series starting from the least significant bit (D0) up to the most significant
bit (D7). Later there is a parity bit, which is a result of a logical XOR
operation on D0-D7 data. The parity bit is optional and does not occur in the
case of this exercise. The termination of the transmission is signaled by the
stop bit (logic level ‘1’).
The sample transmission of the code:
01010011 is presented below:
Fig. 1. Sample transmission of the code: 01010011
using the RS-232 (9600 bps, 8-bits, 1-stop, no parity).
Additional information about RS232
standard:
http://en.wikipedia.org/wiki/RS-232
UCF file for the exercise,
Digilent Spartan-3 board, Spartan-3 3S200 FT256-4:
# Clock:
NET "clk_i" LOC = "T9" ; # 50 MHz clock
# Push-buttons:
NET "rst_i" LOC = "L14" ; # pressed high BTN3
# RS232:
NET "TXD_o" LOC = "R13" ; # RS 232 TXD
NET "RXD_i" LOC = "T13" ; # RS 232 RXD
# Seven-segment LED display:
NET "led7_an_o<3>" LOC = "E13" ; # leftmost digit,
active low
NET "led7_an_o<2>" LOC = "F14" ; # active low
NET "led7_an_o<1>" LOC = "G14" ; # active low
NET "led7_an_o<0>" LOC = "D14" ; # rightmost digit,
active low
NET "led7_seg_o<7>" LOC = "E14" ; # segment 'a',
active low
NET "led7_seg_o<6>" LOC = "G13" ; # segment 'b',
active low
NET "led7_seg_o<5>" LOC = "N15" ; # segment 'c',
active low
NET "led7_seg_o<4>" LOC = "P15" ; # segment 'd',
active low
NET "led7_seg_o<3>" LOC = "R16" ; # segment 'e',
active low
NET "led7_seg_o<2>" LOC = "F13" ; # segment 'f',
active low
NET "led7_seg_o<1>" LOC = "N16" ; # segment 'g',
active low
NET "led7_seg_o<0>" LOC = "P16" ; # segment 'dp',
active low
# LD0 LED:
NET "ld0" LOC = "K12" ; # high on
#