Core Generator (version 1)

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.


Circuit verification

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:

 

RS-232 Transmission
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
#