Embedded System Design - Bubble Sort Algorithm, Embedded System Implementation
Embedded System Design - Bubble Sort Algorithm, Embedded System Implementation
Table of Contents
1 Introduction ......................................................................................................................................4
2 Aim......................................................................................................................................................4
3 Methodology....................................................................................................................................4
3.1 Project Design ........................................................................................................................5
3.1.1 Clock of the System .........................................................................................................6
3.1.2 PS/2 Keyboard Reader ....................................................................................................6
3.1.3 RS-232 Transmitter .............................................................................................................7
3.1.4 Memory of the system .....................................................................................................7
3.1.5 Assembly Code .................................................................................................................8
4 Complete System ............................................................................................................................8
5 Testing the System ...........................................................................................................................9
6 Annex ...............................................................................................................................................10
7 Conclusions .....................................................................................................................................26
8 References ......................................................................................................................................27
Table of Figures
1 Introduction
2 Aim
The purpose of this project is to design a complete embedded system to implement the
bubble sort algorithm that was tested in laboratory 3. This includes the use of a FPGA
development system, which is the VIRTEX-II Microblaze Development Kit board. This project
includes both hardware and software design and encompasses some of key aspects
covered by the course of Embedded System Design (EEET2039).
3 Methodology
As can be seen in Figure 1, the system is divided into three different sections: 1) Keyboard
Receiver, HC11 Core and RS-232 transmitter. The schematic of the design can be seen at
the end of this document in the annex part of this document.
In the hardware design part, the system uses the CPU core (68HC11,
http://www.gmvhdl.com/hc11core.html, 2006/09/13), a PS2 interface and RS232 code
VHDL interfaces. The development of the system will be using the software from Xilinx (Xilinx
ISE 8.1i, www.xilinx.com, 2006/09/01) development tools and ModelSim for simulation.
Xilinx ISE is a fully featured FPGA development environment that enables designs to be
entered as schematics, state charts, or VHDL. Additionally, ModelSim which can be
integrated with Xilinx ISE to simulate the design. In the software design part this project
includes the “Bubble Sort” algorithm implemented using assembly language and then
convert it to the machine code to embed it to the ROM system.
The following will describe the main components of the system. It is clear that the HC11 is
working and it is not necessary to offer any additional explanation about it.
The purpose of this block is to generate the necessary signals for the system. As can be
seen in Figure 3, the block delivers the signals as, E, ph1, ph2 and clk_9600. The last one is
used for the RS_232_W block to write serial data to the dummy terminal.
This block is based on the fact that the Microblaze system has a 24Mhz crystal generator.
The code for this block could be seen in the annex of this document.
The basic code for the keyboard reader is based on rapid prototyping of digital systems
(Hamblen J O, Hall T S and Furman, 2006). Basically this block uses a digital filter to avoid
noise. Using the clock input signal (24 Mhz) it is possible to filter data with a period of 333 ns.
However it is a user discretion to reduce or increase this time. The filter use a shifting register
to create the filter effect. One of the improvements made to this code are, besides others,
the translation of the scan code into ASCII code.
The code of this block can be seen at the annex of this document.
The design of this block is based on the input signal CLK which is the clock reference for the
block. In this design to this CLK is connected the clk_9600 output of the clock generator
block.
9600 bps
8 data bit
1 start bit
1 stop bit
No parity bit
The block produces its output based on the rising edge of the CLK input. The code of this
block could be seen in the annex of this document.
The system uses three VHDL codes as a source of memory, RAM, ROM and DEV blocks. The
last one simulates the presence of ports PA to PE in the microcontroller.
The ram is composed by 10 bytes and the rom is composed by 112 bytes. Additionally, dev
block contains 32 bytes of ram. This memory ram is used by the bubble sort algorithm to put
the data once they are ordered.
Multiplexer
One inconvenient founded at the beginning of this project (from laboratory 3 ) was the
conflict when it is necessary to connect two output signals between them. For instance, it
was necessary to create a multiplexer to avoid this problem. The signal to control the
output of the multiplexer depends of the address given by the HC11 core.
Figure 7: Multiplexer 16 x 8
The internal composition of the multiplexer can be seen in the annex at the end of this
document.
The assembly code used in this project is based on the laboratory 1 for this subject. This
code can be seen in the annex of this document. There is a handshaking necessary to deal
with the data transfer between the VHDL code and the core (Despite the fact that there is
only one FPGA chip it is a way to understand how the system is composed).. This
handshaking will be explained in the next section.
4 Complete System
The interconnection of the different components of this design can be seen in the
schematic annexed at the end of this document.
To deal with the transfer of data between the VHDL code and the core (as it was
described before, despite the fact that there is only one FPGA chip. The way to call VHDL
code and Core it is a way to understand how the system is composed) it was necessary to
create a handshaking system that can be described in the following paragraphs:
The main functions on the system were implemented in hardware, such as read number
from keyboard, convert the user input to an integer, prompt the information for user etc.
For the software design, it just uses the Port E to read the number that the user input. Only
three cases can read from Port E, the number from 0-99, number 251 or number 252 The
numbers from 0-99 (BCD) represent the number should be sorted, the number 251
represents the user will input next number and the 252 represents the user finish inputting
numbers and then the system will do the “Bubble Sort” function to sort these numbers
which were stored in the specific memory. After that, the system will check the memories
which store the numbers, if the size become 0, the program will restart.
The following diagram shows in a clearer way how the system works.
To test the system it is necessary to connect a PS/2 keyboard to the Microblaze PS/2 port
and to connect the serial port of the P160 communication card to a Hyperterminal station
running at 9600, 8, N,1.
1. Prompt the user (via an RS-232 dummy terminal) for numbers ranging in value
from 0-99.
2. Accept and parse user input from PS/2 keyboard.
3. Sort the number into ascending order.
4. Display the correctly sorted numbers back to the user (via an RS232 dummy
terminal).
Print Message:
“Enter numbers to order (0-99):”
NO
User Type
Something?
Do Nothing
YES NO
YES YES
YES
Order the
Numbers
Print Message:
“These are the numbers ordered:”
Figure 9: Flow Diagram of the System when it is working (user point of view)
6 Annex
The following graphs show the different VHDL codes and the assembly code of the design
implemented.
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Wilson Castillo
--
-- Create Date: 22:00:24 10/22/2006
-- Design Name:
-- Module Name: clock_finalProject - Behavioral
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clock_finalProject is
Port ( CLK24Mhz : in STD_LOGIC; --24Mhz = 41.67ns;
begin
do_clkprocess: process (CLK24Mhz)
variable var_control : integer := 0;
variable var_control_9600 : integer := 0;
variable bit9600 : std_logic := '0';
begin
if CLK24Mhz'Event and CLK24Mhz = '1' then
var_control := var_control +1;
--clock creation for HC11 there are 8 steps to create
-- as, E, ph1 and ph2 signals.
if var_control > 8 then
var_control := 1;
end if;
case var_control is
when 1 =>
as <= '0'; E <= '1'; ph1 <= '0'; ph2<='1';
when 2 =>
as <= '0'; E <= '1'; ph1 <= '0'; ph2<='1';
when 3 =>
as <= '0'; E <= '1'; ph1 <= '1'; ph2<='0';
when 4 =>
as <= '0'; E <= '1'; ph1 <= '1'; ph2<='0';
when 5 =>
as <= '0'; E <= '0'; ph1 <= '1'; ph2<='0';
when 6 =>
as <= '1'; E <= '0'; ph1 <= '1'; ph2<='0';
when 7 =>
as <= '1'; E <= '0'; ph1 <= '0'; ph2<='1';
when 8 =>
as <= '0'; E <= '0'; ph1 <= '0'; ph2<='1';
when others =>
null;
end case;
--clock generation for 9600 bits per second
--count 1250 times 20,83 ns
var_control_9600 := var_control_9600 +1;
if var_control_9600 < 1250 then
clk_9600 <= '0';
else
if var_control_9600 < 2500 then
clk_9600 <='1';
else
var_control_9600 := 0;
end if;
end if;
end if; --clk 24Mhz
end process;
end Behavioral;
Figure 10: VHDL Code for clock generator
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Wilson Castillo
--
-- Create Date: 00:02:02 10/23/2006
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity RS_232_W is
Port ( CLK : in STD_LOGIC;
Write : in STD_LOGIC;
Word : in STD_LOGIC_VECTOR (7 downto 0);
TX : out STD_LOGIC;
Done : out STD_LOGIC;
reset : in STD_LOGIC);
end RS_232_W;
LIBRARY IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity keyboard is
port( keyboard_clk, keyboard_data, clock_24Mhz ,
reset, read : in STD_LOGIC;
scan_code : out STD_LOGIC_VECTOR(7 downto 0);
ascii_code : out STD_LOGIC_VECTOR(7 downto 0);
scan_ready : out STD_LOGIC;
scan_error : out STD_LOGIC);
end keyboard;
begin
process (read, ready_set)
begin
if (read'event and read = '1') then
scan_ready <= '0';
end if;
end process;
process (read)
begin
--this is for testing to avoid deletion of read signal.
--according to synthesis read signal is going to be deleted
if read'event and read = '1' then
clock_enable <= not clock_enable;
end if;
end process;
--This process filters the raw clock signal coming from the keyboard using a shift register
and two and gates
--The signal is filtered for 333ns
Clock_filter: process(clock_24Mhz)
begin
--WAIT UNTIL clock_48Mhz'EVENT and clock_48Mhz= '1';
if (clock_24Mhz'EVENT and clock_24Mhz= '1') then
--clock_enable <= NOT clock_enable;
--if clock_enable = '1' then
-- filter keyboard_clk
filter (6 downto 0) <= filter(7 downto 1) ;
filter(7) <= keyboard_clk;
if filter = "11111111" then keyboard_clk_filtered <= '1';
elsif filter= "00000000" then keyboard_clk_filtered <= '0';
end if;
--filter keyboard_data
filter2 (6 downto 0) <= filter2(7 downto 1);
filter2(7) <= keyboard_data;
if filter2 = "11111111" then keyboard_data_filtered <= '1';
elsif filter2 = "00000000" then keyboard_data_filtered <= '0';
end if;
end if;
end process Clock_filter;
entity dev is
--$1000 PortA
--$1003 PortC
--$1004 PortB
--$1008 PortD
--$100A PortE
port (E : in std_logic;
ph1, ph2, reset : in std_logic;
--hc11 ports
PC7 : in std_logic;
-- bus selection
bus_data_sel : out std_logic);
--function provided by Mike Treseler 2006/11/14
--http://www.codecomments.com/archive378-2006-4-904608.html
function char2int(arg : character)
return natural is
begin
return character'pos(arg);
end char2int;
end if;
-- Latch address and rw at address strobe
address:=to_integer(unsigned(bus_addr));
rw:=bus_rw;
if ((address>=base) and (address<(base+size))) then
--data bus selection
bus_data_sel <= '1';
else
bus_data_sel <= '0';
end if;
if ph1 = '0' then
if rw = '1' then
bus_dataout<="ZZZZZZZZ";
end if;
end if;
elsif rising_edge(ph1) then
if ((address>=base) and (address<(base+size))) then
address:=address-base; -- adjust for indexing
--address:=address-16#D000#; -- adjust for indexing
if (rw='1') then -- read
bus_dataout<=mem(address);
-- wait until ph1='0';
-- bus_data<="ZZZZZZZZ"; -- remove driver at end of data valid
else -- write
mem(address)<=bus_datain;
-- wait until ph1='0';
end if;
end if;
end if;
end process;
temporal := 0;
flagPrintDouble := '0';
txSpace := '0';
dataReady <= '0';
sizeOfData <= "00000000";
elsif falling_edge(PC(5)) then
if (flagWriteMem2 ='1') and (mem(firstToPrint-1) = memory2) then
flagWriteMem2 <= '0';
end if;
--put in memory 251=hexFB or 252 = hexFC for ASM code
--PC(6) is a kind of delay. However be sure it does work.
if tx251 = '1' then
memory <= "11111011";
tx251 := '0';
end if;
i := 0;
counter := 0;
end if;
else
dataReady <= '0'; --===RESET DATA READY
--reset read KB command
PB(7) <= '0';
--to print the prompt print message
if flagPrint = '0' then
--transmit the prompt message
if i < promptMsgSize then
PA <= printMsg(i);
--write through RS232
if PC(6) = '0' then
PB(6) <= '1';
end if;
--rs232 finished
if (PC(6) = '1') and (flagPC6Control = '0') then
i := i+1;
end if;
else
--finish printing prompt Print message
flagPrint := '1';
i:= 0;
end if;
else --flagPrint == 1
--ASM code put the number of data to print (< 100). It is assumed i=0.
if (i < to_integer(unsigned(mem(firstToPrint-1)))) then--and
(to_integer(unsigned(mem(firstToPrint-1))) < 100) then
if (to_integer(unsigned(mem(firstToPrint +i))) > 10) and (flagPrintDouble ='0')
and (flagPrintHighReady = '0') then
flagPrintDouble := '1';
--temporal := to_integer(unsigned(mem(firstToPrint+i))) / 10;
temporal := to_integer(unsigned(mem(firstToPrint+i)(7 downto 4)));
elsif flagPrintDouble = '0' then
--temporal := to_integer(unsigned(mem(firstToPrint+i))) -
to_integer(unsigned(mem(firstToPrint+i)))/10;
temporal := to_integer(unsigned(mem(firstToPrint+i)(3 downto 0)));
--flag := '0';
end if;
if txSpace = '0' then
PA <= std_logic_vector(to_unsigned(temporal+16#30#,8));
else
PA <= "00100000";
end if;
--write through RS232
if PC(6) = '0' then
PB(6) <= '1';
end if;
--RS232 finished
if (PC(6) = '1') and (flagPC6Control = '0') then
if txSpace = '1' then
txSpace := '0';
elsif flagPrintDouble = '0' then
i := i+1;
txSpace := '1';
flagPrintHighReady := '0';
elsif flagPrintDouble = '1' then
flagPrintDouble := '0';
flagPrintHighReady := '1';
end if;
end if;
elsif to_integer(unsigned(mem(firstToPrint-1))) /= 0 then
--it means that we finish printing. So start again.
print <= '0';
start := '1';
flagPrint := '0';
i := 0;
PB(6) <= '0';
dataReady <= '0';
memTest(0) <= "00000000";--Do I need this?.
--mem(firstToPrint-1) := "00000000";
memory2 <= "00000000"; --write 0 in memory
--Flag to write in memory outside cycle.
flagWriteMem2 <= '1';
end if;
end if; -- flagPrint
--To avoid double entering to the same function.
if (PC(6) = '1')then
PB(6) <= '0';
if (flagPC6Control = '0') then
flagPC6Control := '1';
end if;
--RECEIVING DATA
if (receiving = '1') then
--reset order Write RS232
if (PC(6) = '1') then --and (flagPC6Control = '0') then
PB(6) <= '0';
end if;
--KB finished
if (PC7 = '1') and (FlagPC7Control = '0') then
--SET FLAG TO AVOID ENTERING AGAIN TO THIS IF
FlagPC7Control := '1';
--reset cmd reading KB
PB(7) <= '0';
--waiting for number and number received less than 10
if (waitNumber='1') then
--PE between x'30 and x'39
if ( (PE >= "00110000") and (PE <= "00111001") )then
--transfer data to portA
PA <= PE;
--order write through RS232
PB(6) <= '1';
if firstNumber = '0' then
number := to_integer(unsigned(PE)) - 16#30#;
firstNumber := '1';
else
number := number*16 + to_integer(unsigned(PE)) - 16#30#;
firstNumber := '0';
waitNumber := '0';
waitSpace := '1';
--put data in memory
memory <= std_logic_vector(to_unsigned(number,8));
memTest(0) <= std_logic_vector(to_unsigned(i,8));
memTest(i+1) <= std_logic_vector(to_unsigned(number,8));
i := i+1;
end if;
end if;
PA <= PE;
PB(6) <= '1';
memory <= "11111100"; --put 252 in the memory last number;
firstNumber := '0';
receiving <= '0';
--print <= '1';
waitSpace := '0';
tempSizeOfData := i+1;
memTest(0) <= std_logic_vector(to_unsigned(tempSizeOfData,8));
memTest(i+1) <= std_logic_vector(to_unsigned(number,8));
i := 0;
end if;
end if;
if (tempSizeOfData /= 0) and (i = 0) then
print <= '1';
end if;
else -- PC7'Event
if PC7 = '0' then
PB(7) <= '1';
flagPC7Control := '0';
end if;
end if; --PC7'Event
end if; --receiving
end if;
end process;
end behavior;
Figure 14: VHDL Code for Devices handler
END HC11CoreSchematic_HC11CoreSchematic_sch_tb;
ARCHITECTURE behavioral OF HC11CoreSchematic_HC11CoreSchematic_sch_tb IS
COMPONENT HC11CoreSchematic
PORT( PH2 : OUT STD_LOGIC;
PB : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
DATAOUTROM : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
DATAOUTRAM : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
keyboard_clk : IN STD_LOGIC;
keyboard_data : IN STD_LOGIC;
DATA : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
DATAW : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
SEL_ROM : OUT STD_LOGIC;
SEL_DEV : OUT STD_LOGIC;
AS : OUT STD_LOGIC;
E : OUT STD_LOGIC;
ADD : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
PH1 : OUT STD_LOGIC;
CLK : IN STD_LOGIC;
--This function returns '1' is parity is not even eg. '1' is Vector is Odd.
function Odd (Vector : std_logic_vector) return std_logic is
variable parity : std_logic := '0';
begin
for i in Vector'range loop
parity := parity xor Vector(i);
end loop;
return parity;
end function;
BEGIN
7 Conclusions
The design of embedded systems implies different aspects as costs and engineering time.
This project had to do with engineering time. Furthermore to reduce engineering time it is
necessary to have a good knowledge of the system to implement (It is called requirement
analysis). On the other hand is the technical aspect. Moreover to get success in the
embedded system implementation it necessary to have deeply knowledge of the tools
that we as engineers are going to use. They could be development systems, chips (FPGA,
PLD, microcontrollers, DSPs…)
In fact this project took some of our time to get familiar with the Microblaze system.
However at the end we got confident reprogramming several times the system. For
instance, we could say that the next development should take much more less time than
the this first one.
On the other hand is the knowledge that we had to know about VHDL and moreover VHDL
synthesis. The main idea of the synthesis is to allow engineers to think about the design in a
higher level because the synthesis tool is in charge of the register level (Ashenden P J,
2002).
There are several constrains when it is necessary to put the design to the synthesis tool:
variable types, clocking schemes, processes and subprograms among others.
This project forced us to study some of them. However, it is a matter of practice and
experience that us as engineers will be able to get deeply knowledge of the VHDL
synthesis theory. Additionally, the synthesis process depends mainly of the synthesis tool
used, in this project we used ISE 8.1i from Xilinx.
Regarded with the development of the project we used Modelsim as a simulation tool to
develop the major part of the system. However, as we described before one result could
be obtained from the simulation tool and other from the synthesis tool(implementation in
the chip). In fact, sometimes we get good results in the simulation but they were not the
same in the implementation. For instance, we had to use other kind of methodology to
trace parts of the program in order to get information of where the system failed in our
tests. For example, we had to use the displays on the Microblaze system as flag indicators
to know where the program stopped or crashed.
In conclusion, this project was really instructive for us, we got the real experience trying to
solve a real life problem. Despite the fact that the system to implement was not complex,
we got a much better understanding about embedded systems, FPGA, development
systems, VHDL and VHDL synthesis among others.
8 References
Amstrong J R and Gail F, 2000, VHDL Design Representation and Synthesis, 2nd Edition,
Prentice Hall Modern Semiconductor Design Series, New Jersey.
Ashenden P J, 2002, The Designer’s Guide to VHDL,2nd Edition, Morgan Kaufmann Publishers,
London.
Beckett P, 2006, EEET2039 Embedded System Design Lecture Notes, RMIT University,
Electrical and Computer Engineering School, Melbourne.
Cohen B, 1999, VHDL Coding Styles and Methodologies, 2nd Edition, Kluwer Academic
Publishers, Norwell.
Cuzeau, B., 2003, Simple PS/2 interface, http://www.alse-fr.com.
Hamblen J O, Hall T S and Furman M D, 2006, Rapid Prototyping of Digital Systems, Quartus II
Edition, Springer, USA.
A A
kbClk_Led
INV
kbData_Led
INV
keyboard ASCII_CODE(7:0)
debug_CCR(7:0)
E DATAOUTRAM(7:0) SEL_ROM
PH2
GND
BUF
ph1
debug_Y(15:0) PC0
ph2 BUF
debug_SP(15:0) debug_SP(15:0)
PC1
data(7:0)
reset
debug_micro(3:0) BUF
PC2
as
BUF
bus_rw PC3
BUF
bus_addr(15:0)
PC4
bus_datain(7:0)
bus_dataout(7:0) BUF
BUF
D D
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
MUXF6
I0
A IN0(7:0) A
O
OUTS(7:0)
I1
MUXF6
I0
O
I1
MUXF6
I0
O
B B
I1
MUXF6 Multiplexor 16 x 8
I0
O
I1
MUXF6
I0
O
I1
S
C
MUXF6 C
I0
O
I1
MUXF6
I0
IN1(7:0) O
I1
MUXF6
I0
D D
O
I1
1 2 3 4 5 6 7 8