Você está na página 1de 51

System On Chip Design

ALTERA Cyclone II

Edgar Siles

Edgar Siles
PIO NiosII System(Hardware/Software)
SYSTEM INFORMATION
System clock: 50 MHz
System components:
Processor: NiosII
Version and features: NiosII/f RISC: Instruction cache: Branch prediction:
Barrel shifter
Instruction cache: Yes: 4K
Data cache: Yes: 2k
Debugging facility: Level 1
Reset vector memory: onchip_memory2_0.s1
Reset vector offset: 0x00000000
Reset vector: 0x00080000
Exception vector memory: onchip_memory2_0.s1
Exception vector offset: 0x00000020
Exception vector: 0x00008020
Memory:
Type: RAM Writable [On Chip]
Data width: 32 Bit
Address width: 32K x 15
Size: 32K x 32
Read latency: Slave S1, S2 latency 1
Peripheral components:
MASTER
Nios2_qsys_0
SLAVES
Interrupt level: nios2_qsys_0 IRQ base: 0 | jtag_uart_0 IRQ: 2
JTAG timer:
Write [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
Read [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
System ID Parameter: 1
Parallel PIO:
7-Segment: {High and Low, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 7
Buttons: {High and Low, INPUT}
Output bits: 2
LEDs: {8 Green LEDs, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 8

Linker segment mappings:


This is the diagram of where the design is stored with in the FPGA.

System memory map:


These are the addresses where each component of the design is located.

BDF SYSTEM DIAGRAM


Top level design:

Qsys SYSTEM DIAGRAM


Qsys diagram:
This represents the inner connections of the design, with in the FPGA. It illustrates how
the peripherals are connected, and the master slave relations with in the design. The base
addresses are also assigned here and the reset and clock inputs to which the design will run.

CODE PROGRAM
C code:
/*Edgar Siles
ECE 520L
Lab 2 : Nios Introduction and initial procedures.
This is a program to have counters which will be used as a military time watch display.
It will make use of the :usleep(): to count for time. It must also be compact to fit in the 2K mem.
For the usleep() function, it waits for the amount of microseconds placed in the function. It will
also make use of some of the on board switches to modify the output to use the 7-Segment, LED's
and monitor, as visual displays. Initially LED's-Off, 7-Seg.-00, and initial time is 00:00:00 it will also
allow user input depending on the button selection using the keyboard.
Example: 23:59:59*/
/**/
#include<stdio.h>
#include"alt_types.h"

#include"altera_avalon_pio_regs.h"
#include"sys/alt_irq.h"
#include"sys/alt_stdio.h"
#include"system.h"
//Define the base address location of the peripherals
#define SWITCH_BASE_ADDRESS 0x00011030
#define LED_BASE_ADDRESS 0x00011020
#define SVN_SEG_H_BASE_ADDRESS 0x00011000
#define SVN_SEG_L_BASE_ADDRESS 0x00011010

int svn_seg_decoder(int a)
{
int out=0;
//The 7-Seg. decoder to display the proper number
//Low lights up the 7-Seg.
/* 0
5| 6 |1
4| _ |2
3
bit # ordering = 6543210 = gfedcba
*/
switch( a )
{
case 0:
out = 64; //Represents 1000000;
break;
case 1:
out = 121; //Represents 1111001;
break;
case 2:
out = 36; //Represents 0100100;
break;
case 3:
out = 48; //Represents 0110000;
break;
case 4:
out = 25; //Represents 0011001;
break;
case 5:
out = 18; //Represents 0010010;
break;
case 6:
out = 2; //Represents 0000010;
break;
case 7:
out = 120; //Represents 1111000;
break;
case 8:
out = 0; //Represents 0000000;
break;

case 9:
out = 24; //Represents 0011000;
break;
default :
out = 0; //Represents 0000000;
break;
}
return out;
}

int main()
{
//Declare variables
int sec1,sec2,min1,min2,hr1,hr2,cnt,sw;
char h1,h2,m1,m2,s1,s2;
//Initiate variables
sec1=0; min1=0; hr1=0; sec2=0; min2=0; hr2=0;
//sw=1;//TESTING PARAMETER
//Calculate time
//1us = 1E-6s => 1,000,000us = 1s [Actual implementation]
//For testing purposes 60ms will represent 1sec, 1s will represent 1hour and 24s a 1day
//1ms = 1000us
while(1)
{
usleep(1000);//runs for 1ms
cnt=cnt+1;//to be used as a seperate counter
if(cnt==1000)//Checks for sec to increase
{
sec1++;
cnt=0;
if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==1)
{
//LED's off and 7-Seg. display seconds, monitor display[minutes]
alt_printf("HH:MM:%c%c \n",(char)sec2+'0',(char)sec1+'0');
}
if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==2)
{
//LED's display minutes and 7-Seg. display seconds, monitor display
alt_printf("HH:%c%c:SS \n",(char)min2+'0',(char)min1+'0');
}
if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==3)
{
alt_printf("%c%c:%c%c:%c%c
\n",(char)hr2+'0',(char)hr1+'0',(char)min2+'0',(char)min1+'0',(char)sec2+'0',(char)sec1+'0');
}
}
if(sec1==10)//Checks for sec to increase ones place
{
sec2++;
sec1=0;
}

if(sec2==6)//Checks for sec to increase tens place


{
min1++;
sec2=0;
}
if(min1==10)//Checks for min to increase ones place
{
min2++;
min1=0;
}
if(min2==6)//Checks for min to increase hr and tens place
{
hr1++;
min2=0;
}
if(hr1==10)//Checks for clock reset and repeat
{
hr2++;
hr1=0;
}
if(hr2==2)//Checks for clock reset and repeat
{
if(hr1 == 4)
{
hr2=0;
hr1=0;
}
}
//Begins the display options according to the switches.
//Diasplay results
//if(sw=1)//TESTING PARAMETER
if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==0)
{
//LED's off and 7-Seg. 00, Write 0's to LED's and 1's to 7-Seg.
//User input section for hr, min and sec.
alt_printf("Enter the hour's first digit #0:00:00, ");
alt_printf("Press ENTER when input is complete: ");
h2 = alt_getchar();
hr2=(int)h2-'0';
while (h2 != '\n')
h2 = alt_getchar();
alt_printf("Enter the hour's Second digit 0#:00:00, ");
alt_printf("Press ENTER when input is complete: ");
h1 = alt_getchar();
hr1=(int)h1-'0';
while (h1 != '\n')
h1 = alt_getchar();
alt_printf("Enter the minutes fist digit 00:#0:00, ");
alt_printf("Press ENTER when input is complete: ");
m2 = alt_getchar();
min2=(int)m2-'0';
while (m2 != '\n')
m2 = alt_getchar();
alt_printf("Enter the minutes second digit 00:0#:00, ");
alt_printf("Press ENTER when input is complete: ");

m1 = alt_getchar();
min1=(int)m1-'0';
while (m1 != '\n')
m1 = alt_getchar();
alt_printf("Enter the seconds fist digit 00:00:#0, ");
alt_printf("Press ENTER when input is complete: ");
s2 = alt_getchar();
sec2=(int)s2-'0';
while (s2 != '\n')
s2 = alt_getchar();
alt_printf("Enter the seconds second digit 00:00:0#, ");
alt_printf("Press ENTER when input is complete: ");
s1 = alt_getchar();
sec1=(int)(s1)-'0';
while (s1 != '\n')
s1 = alt_getchar();
//printf("%c%c:%c%c:%c%c \n",h2,h1,m2,m1,s2,s1);//TESTING PARAMETER
//sec1=int(s1); min1=int(m1); hr1=int(h1); sec2=int(s2); min2=int(m2); hr2=int(h2);
// printf("%i%i:%i%i:%i%i \n",hr2,hr1,min2,min1,sec2,sec1);//TESTING PARAMETER
//Turn off 7-Seg.
IOWR(SVN_SEG_H_BASE_ADDRESS,0,0000000);
IOWR(SVN_SEG_L_BASE_ADDRESS,0,0000000);
//Turn off LED's
IOWR(LED_BASE_ADDRESS,0,00000000);
//No monitor display
}
else if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==1)
{
//LED's off and 7-Seg. display seconds, monitor display[minutes]
//Function to write to 7-Seg the proper number[seconds]
IOWR(SVN_SEG_H_BASE_ADDRESS,0,svn_seg_decoder(sec2));
IOWR(SVN_SEG_L_BASE_ADDRESS,0,svn_seg_decoder(sec1));
//Turns off LED's
IOWR(LED_BASE_ADDRESS,0,00000000);

}
else if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==2)
{
//LED's display minutes and 7-Seg. display seconds, monitor display
//Function to write to 7-Seg the proper number[seconds]
IOWR(SVN_SEG_H_BASE_ADDRESS,0,svn_seg_decoder(sec2));
IOWR(SVN_SEG_L_BASE_ADDRESS,0,svn_seg_decoder(sec1));
//Function to write to LED's the proper number[minutes]
IOWR(LED_BASE_ADDRESS,0,((min2*10)+min1));
}
else //if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==3) condition
{
//printf("%i%i:%i%i:%i%i \n",hr2,hr1,min2,min1,sec2,sec1);//TESTING PARAMETER
//Function to write to 7-Seg the proper number[seconds]
IOWR(SVN_SEG_H_BASE_ADDRESS,0,svn_seg_decoder(sec2));
IOWR(SVN_SEG_L_BASE_ADDRESS,0,svn_seg_decoder(sec1));
//Function to write to LED's the proper number[seconds]
IOWR(LED_BASE_ADDRESS,0,((sec2*10)+sec1));
}
}
return 0;
}

PROGRAM OUTCOME
Output:
Monitor Display:
LED Display: ON 7-Seg. Display: ON Switch Positions: 00

LED Display: OFF 7-Seg. Display: ON Switch Positions: 01

LED Display: ON 7-Seg. Display: ON Switch Positions: 10

FIG 1

LED Display: ON 7-Seg. Display: ON Switch Positions: 11

Represents 38 in 7-segment and LEDs. [ + +


]
FIG 2
DISCCISION/CONCLUSION
As it is shown, the program works as desired with the proper output to input
combinations. FIG 1 shows how the user input is accepted and correctly placed in the proper
variables in the system and the roll-over of the time to the desires specifications with their
respective button selection. FIG 2 shows the proper display with the proper combination in the
LED and 7-segment displays on the ALTERA DE2 board. The only issue that might be of
concern is when setting the time though the switch option 00. When setting the time, as long as
the switch is in this position the design keeps asking for the input until the switches are changed
from position. This is what the design requires but it might be better to only ask for the time
once, and wait for the combination to be set again before asking for the time again. This can
easily be accomplished by using a flag to control the input.
This design asked for a lot of optimization since the memory usage was restricted to the
onboard 2k space. This crated issues when the design was to interact with the user since it was to
output messages and input values. The first approach was the standard printf(), and getchar()
commands to interact, but as expected theses were too large to be implemented in this design and
some were not compatible. In order to solve the problem we use the ALT_ functions that reduced
the footprint significantly and allowed for the program to fit in the memory. Without the ALT_
functions the program required 23140 Bytes more of memory. In order to use the ALT_
functions, the proper BSP settings had to be used in addition to the conditions these functions
required. While messing around with the BSP setting, it was discovered that the ALT_ functions
do not comply with the C++ or small C library therefore the only optimization available is the
reduced drivers. One other restriction on using the ALT_ functions is that they only work on
characters therefore required functions to convert the signals.

LCD Initialization
--This is the state machine to initialize the LCD touch screen in order to be able to display
--images and accept input. It will set the screen resolution at 800 x 480 pixel resolution with active
--low support for synchronization. It will be a normal, non-inverted, display. It is also to satisfy the
--proper timing restrictions. Assuming the clk input is at 50 MHz, which will be modulated to the 500KHz
--that are required, the max frequency that this clock can be is 3.12 MHz
LIBRARY ieee;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY Hw2_1 IS
PORT(
clk: IN STD_LOGIC;
data_out : OUT STD_LOGIC;
SCEN : OUT STD_LOGIC
);
END Hw2_1;
ARCHITECTURE behavior OF Hw2_1 IS
------------------------------------SIGNALS---------------------------------------SIGNAL data, enable : STD_LOGIC := '0';
--DIVIDED CLOCK
SIGNAL clk_div : STD_LOGIC;
SIGNAL cnt : INTEGER RANGE 0 TO 100;
--REGISTER DATA SELECTION
SIGNAL su, reg_cnt : INTEGER RANGE 0 TO 3 := 0;
SIGNAL done : INTEGER RANGE 0 TO 20;
TYPE arr IS ARRAY (0 TO 2) OF STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL arr_a : arr;
SIGNAL reg_eval : std_logic_vector(15 downto 0);
-- Build an enumerated type for the state machine
TYPE state_type IS (set_up, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16);
-- Register to hold the current state
SIGNAL state : state_type;
BEGIN
------------------------------------PROCESS---------------------------------------PROCESS(clk)
BEGIN
--PLACES THE DESIRES REGISTER PROPERTIES IN AN ARRAY
arr_a (0) <= "0000101100000111";--REGISTER 2
arr_a (1) <= "1000111111011111";--REGISTER 3
arr_a (2) <= "0001001100010111";--REGISTER 4
IF(clk' EVENT AND clk = '1') THEN--RISING EDGE MODULATED CLK SIGNAL
--counters for the clks and generating signals

--GENERATES THE 500KHz CLOCK TO RUN THE SYSTEM


--FROM THE 50MHz FPGA CLOCK
cnt <= cnt +1;
IF(done = 20)THEN--RESETS ALL THE PARAMETERS TO RESTART THE STATE MACHINE
SCEN <= '1';
su <= 0;
enable <= '0';
done <= 0;
END IF;
IF(cnt = 100 )THEN
clk_div <= '1';--KNOWN AS ADC_CLK
done <= done + 1;
IF(su < 3)THEN
su <= su+1;
IF(su = 1)THEN
SCEN <= '0';--TO BE USED AS THE ADC CONTROL SIGNAL
END IF;
IF(su = 2)THEN
enable <= '1';
reg_eval <= arr_a (reg_cnt);
IF(reg_cnt < 2)THEN
reg_cnt <= reg_cnt + 1;
END IF;
END IF;
END IF;
cnt <= 0;
ELSE
clk_div <= '0';
END IF;
END IF;
END PROCESS;
------------------------------------STATE 1-16-------------------------------------PROCESS(clk_div,enable)
BEGIN
--THIS IS THE STATE MCHINE THAT CONTROLS THE SERIAL COMMUNICATION TO INITIALIZE
--THE DISPLAY WILL GO THROUGH THE DESIRED REGISTERS THEN WHEN DONE JUST CYCLE
--IN THE LAST STATE INDEFINETLY. RISING EDGE AND ENABLE CONTROLLED, BOTH HIGH.
IF(clk_div' EVENT AND clk_div = '1') THEN
IF(enable = '1') THEN
CASE state IS
WHEN set_up=>
state <= s0;
WHEN s0=>
state <= s1;
WHEN s1=>
state <= s2;
WHEN s2=>
state <= s3;

WHEN s3 =>
state <= s4;
WHEN s4=>
state <= s5;
WHEN s5=>
state <= s6;
WHEN s6=>
state <= s7;
WHEN s7 =>
state <= s8;
WHEN s8=>
state <= s9;
WHEN s9=>
state <= s10;
WHEN s10=>
state <= s11;
WHEN s11=>
state <= s12;
WHEN s12 =>
state <= s13;
WHEN s13=>
state <= s14;
WHEN s14=>
state <= s15;
WHEN s15=>
state <= s16;
WHEN s16 =>
state <=set_up ;
END CASE;
END IF;
END IF;
END PROCESS;
-- MOORE MACHINE: OUTPUT SOLEY DEPENDS ON THE INPUT
PROCESS (state,reg_eval)
BEGIN
--OUTPUT TO THE STATE MACHINE
CASE state IS
WHEN set_up =>
data_out <= '0';--REGISTER IDENTIFICATION
WHEN s0 =>
data_out <= reg_eval(15);--REGISTER IDENTIFICATION
WHEN s1 =>
data_out <= reg_eval(14);
WHEN s2 =>
data_out <= reg_eval(13);
WHEN s3 =>
data_out <= reg_eval(12);

WHEN s4 =>
data_out <= reg_eval(11);
WHEN s5 =>
data_out <= reg_eval(10);
WHEN s6 =>
data_out <= reg_eval(9);--READ/WRITE
WHEN s7 =>
data_out <= reg_eval(8);--HiZ
WHEN s8 =>
data_out <= reg_eval(7);--DATA
WHEN s9 =>
data_out <= reg_eval(6);
WHEN s10 =>
data_out <= reg_eval(5);
WHEN s11 =>
data_out <= reg_eval(4);
WHEN s12 =>
data_out <= reg_eval(3);
WHEN s13 =>
data_out <= reg_eval(2);
WHEN s14 =>
data_out <= reg_eval(1);
WHEN s15 =>
data_out <= reg_eval(0);
WHEN s16 =>
data_out <= '0';
END CASE;
END PROCESS;
END behavior;

Shows the cycling of the registers[2,3,4] and the repetition at the end.

Shows the first cycle cming out with its respective state: reg 2 = 0000101100000111

The register change cycle (Final stages of the state machine) and signal resetting to restart the state
machine. Shows the SCEN goes on before the enable.

Edgar Siles
Polling NiosII System (Hardware/Software)
SYSTEM INFORMATION
System clock: 50 MHz
System components:
Processor: NiosII
Version and features: NiosII/s RISC: Instruction cache: Branch prediction:
Hardware multiply: Hardware divide
Instruction cache: Yes: 4K
Data cache: Yes: 2k
Debugging facility: Level 1, software breakpoints
Reset vector memory: onchip_memory2_0.s1
Reset vector offset: 0x00000000
Reset vector: 0x00080000
Exception vector memory: onchip_memory2_0.s1
Exception vector offset: 0x00000020
Exception vector: 0x00008020
Memory:
Type: RAM Writable [On Chip]
Data width: 32 Bit
Address width: 32K x 15
Size: 32K x 32
Read latency: Slave S1, S2 latency 1
Peripheral components:
MASTER
Nios2_qsys_0
SLAVES
Interrupt level: nios2_qsys_0 IRQ base: 0 | jtag_uart_0 IRQ: 2
JTAG timer:
Write [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
Read [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
System ID Parameter: 1
Parallel PIO:
7-Segment: {High and Low, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 7
Buttons: {High and Low, INPUT}
Output bits: 2
LEDs: {8 Green LEDs, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 8
LCD Display: {OUTPUT}

Optrex 16207 16x2 Character LCD panel


Interval Timer:
Period: 1 second
Count size: 32
Preset: Custom
SETS: ONLY Fixed period, No Start/Stop control bits.

Linker segment mappings:


This is the diagram of where the design is stored with in the FPGA.

System memory map:


These are the addresses where each component of the design is located within the memory.
They represent the system.h base addresses.

BDF SYSTEM DIAGRAM


Top level design:

Qsys SYSTEM DIAGRAM


Qsys diagram:

This represents the inner connections of the design, with in the FPGA. It illustrates how
the peripherals are connected, and the master slave relations with in the design. The base
addresses are also assigned here and the reset and clock inputs to which the design will run.
CODE PROGRAM
C code:
/*Edgar Siles
ECE 520L
Lab 4 : Nios Introduction and initial procedures. This is a program to have
counters which will be used as a military time watch display. It will make
use of the :TIMER: to count for time. It must also be compact to fit in the
2K mem. For the timer function, it waits for the amount of microseconds
placed in the function set the flag and since we are polling it will then
increase the sec. It will also make use of some of the on board switches to
modify the output to use the 7-Segment, LED's and monitor and LCD display, as
visual displays. Initially LED's-Off,7-Seg.-00, and initial time is 00:00:00
It will also allow user input depending on the button selection. Example:
23:59:59*/
#include<stdio.h>
#include<unistd.h>
#include"alt_types.h"
#include"altera_avalon_pio_regs.h"
#include"sys/alt_irq.h"
#include"system.h"
//Define the base address location of the peripherals
#define SWITCH_BASE_ADDRESS 0x00011050
#define LED_BASE_ADDRESS 0x00011040
#define SVN_SEG_L_BASE_ADDRESS 0x00011020
#define SVN_SEG_H_BASE_ADDRESS 0x00011030
#define LCD_BASE 0x00011060
#define LCD_COMMAND_REG_WR 0
#define LCD_DATA_REG_WR 2
#define LCD_DATA_REG_RD 3
int svn_seg_decoder(int a)
{
int out=0;
//The 7-Seg. decoder to display the proper number
//Low lights up the 7-Seg.
/*0

5| 6 |1
4| _ |2
3
bit # ordering =
*/
switch( a )
{
case 0:
out = 64;
break;
case 1:
out = 121;
break;
case 2:
out = 36;
break;
case 3:
out = 48;
break;
case 4:
out = 25;
break;
case 5:
out = 18;
break;
case 6:
out = 2;
break;
case 7:
out = 120;
break;
case 8:
out = 0;
break;
case 9:
out = 24;
break;
default :
out = 0;
break;
}
return out;

6543210 or gfedcba

//Represents 1000000;
//Represents 1111001;
//Represents 0100100;
//Represents 0110000;
//Represents 0011001;
//Represents 0010010;
//Represents 0000010;
//Represents 1111000;
//Represents 0000000;
//Represents 0011000;
//Represents 0000000;

}
int main()
{
//Declare variables
int sec1,sec2,min1,min2,hr1,hr2;
char h1,h2,m1,m2,s1,s2;
//Initiate variables
sec1=0;min1=0;hr1=0;sec2=0;min2=0;hr2=0;
//Calculate time
//Set function code 4 times--8 bit, 2 line, 5x7 mode

IOWR(LCD_BASE,LCD_COMMAND_REG_WR,0x38);
usleep(4100);//4.1 ms wait
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x38);
usleep(100);//4.1 ms wait
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x38);
usleep(100);//4.1 ms wait
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x38);
usleep(100);//4.1 ms wait
//Display off
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x08);
usleep(40);//40 us wait
//Display on
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x0C);
usleep(40);//40 us wait
//Set entry mode, cursor increment,no display shift
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x06);
usleep(40);//40 us wait
//Clear the display
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x01);
usleep(15200);//15.2 ms wait
//Initiate the Timer
IOWR(TIMER_BASE,1,6);
while(1)
{
//Timer will run here to increment the seconds therefore the time
if(sec1==10)//Checks for sec to increase ones place
{
sec2++;
sec1=0;
}
if(sec2==6)//Checks for sec to increase tens place
{
min1++;
sec2=0;
}
if(min1==10)//Checks for min to increase ones place
{
min2++;
min1=0;
}
if(min2==6)//Checks for min to increase hr and tens place
{
hr1++;
min2=0;
}
if(hr1==10)//Checks for clock reset and repeat
{
hr2++;
hr1=0;
}
if(hr2==2 && hr1==4)//Checks for clock reset and repeat
{
hr2=0;
hr1=0;

}
if((IORD(TIMER_BASE,0)& 1) == 1 )//Time out occurred
{
//Display options from buttons
switch(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0))
{
case 1:
//01 monitor display[seconds]
alt_printf("HH:MM:%c%c \n",(char)sec2+'0',(char)sec1+'0');
//Function to write to 7-Seg the proper number[seconds]
IOWR(SVN_SEG_H_BASE_ADDRESS,0,svn_seg_decoder(sec2));
IOWR(SVN_SEG_L_BASE_ADDRESS,0,svn_seg_decoder(sec1));
//LED's unchanged
//Function to write seconds to the LCD
IOWR(LCD_BASE,LCD_COMMAND_REG_WR, 0x80);
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_DATA_REG_WR, (char)sec2+'0');
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x81);
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_DATA_REG_WR, (char)sec1+'0');
usleep(40);//40 us wait
break;
case 2:
//10 monitor display [minutes]
alt_printf("HH:%c%c:SS \n",(char)min2+'0',(char)min1+'0');
//Function to write to 7-Seg the proper number[seconds]
IOWR(SVN_SEG_H_BASE_ADDRESS,0,svn_seg_decoder(sec2));
IOWR(SVN_SEG_L_BASE_ADDRESS,0,svn_seg_decoder(sec1));
//Function to write to LED's the proper number[minutes]
IOWR(LED_BASE_ADDRESS,0,(min2*10)+min1);
//Function to write minutes to the LCD
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x80);
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_DATA_REG_WR, (char)min2+'0' );
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x81);
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_DATA_REG_WR, (char)min1+'0' );
usleep(40);//40 us wait
break;
case 3:
//11 monitor display [hr min sec] for functionality
alt_printf("%c%c:%c%c:%c%c\n",(char)hr2+'0',(char)hr1+'0',(char)min2+'0',(cha
r)min1+'0',(char)sec2+'0',(char)sec1+'0');
//Function to write to 7-Seg the proper number[seconds]
IOWR(SVN_SEG_H_BASE_ADDRESS,0,svn_seg_decoder(sec2));
IOWR(SVN_SEG_L_BASE_ADDRESS,0,svn_seg_decoder(sec1));
//Function to write to LED's the proper number[seconds]
IOWR(LED_BASE_ADDRESS,0,((sec2*10)+sec1));
//Function to write seconds to the LCD
IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x80);
usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_DATA_REG_WR, (char)sec2+'0' );
usleep(40);//40 us wait

IOWR(LCD_BASE, LCD_COMMAND_REG_WR, 0x81);


usleep(40);//40 us wait
IOWR(LCD_BASE, LCD_DATA_REG_WR, (char)sec1+'0' );
usleep(40);//40 us wait */
break;
}
//Increases the seconds
sec1++;
//Resets the timer to start counting again
IOWR(TIMER_BASE,0,0);
}
//Begins the display options according to the switches.
//Display results
if(IORD_8DIRECT(SWITCH_BASE_ADDRESS,0)==0)
{
//Change time, No display LCD, LED's off and 7-Seg. 00
//Input the time. User input section for hr, min and sec.
alt_printf("Enter the hour's first digit #0:00:00, ");
alt_printf("Press ENTER when input is complete: ");
h2 = alt_getchar();
hr2=(int)h2-'0';
while (h2 != '\n')
h2 = alt_getchar();
alt_printf("Enter the hour's Second digit 0#:00:00, ");
alt_printf("Press ENTER when input is complete: ");
h1 = alt_getchar();
hr1=(int)h1-'0';
while (h1 != '\n')
h1 = alt_getchar();
alt_printf("Enter the minutes fist digit 00:#0:00, ");
alt_printf("Press ENTER when input is complete: ");
m2 = alt_getchar();
min2=(int)m2-'0';
while (m2 != '\n')
m2 = alt_getchar();
alt_printf("Enter the minutes second digit 00:0#:00, ");
alt_printf("Press ENTER when input is complete: ");
m1 = alt_getchar();
min1=(int)m1-'0';
while (m1 != '\n')
m1 = alt_getchar();
alt_printf("Enter the seconds fist digit 00:00:#0, ");
alt_printf("Press ENTER when input is complete: ");
s2 = alt_getchar();
sec2=(int)s2-'0';
while (s2 != '\n')
s2 = alt_getchar();
alt_printf("Enter the seconds second digit 00:00:0#, ");
alt_printf("Press ENTER when input is complete: ");
s1 = alt_getchar();
sec1=(int)(s1)-'0';
while (s1 != '\n')
s1 = alt_getchar();
//Turn off 7-Seg.
//Turn off LED's, Write 0's to LED's
//No monitor display
//Function to write clear the LCD

}
}
return 0;
}

PROGRAM OUTCOME
Output:
Monitor Display:
LED Display: ON 7-Seg. Display: ON Switch Positions: 00

LED Display: OFF 7-Seg. Display: ON Switch Positions: 01

LED Display: ON 7-Seg. Display: ON Switch Positions: 10

FIG 1

DISCCISION/CONCLUSION
As it is shown, the program works as desired with the proper output to input
combinations. FIG 1 shows how the user input is accepted and correctly placed in the proper
variables in the system and the roll-over of the time to the desires specifications with their
respective button selection. The only issue that might be of concern is character location in the
LCD display. This can easily be taken care off by calling the command register and [lacing the
cursor in the correct location.
This design asked for a lot of optimization since the memory usage was restricted to the
onboard 2k space. This created issues when the design was to interact with the user since it was
to output messages and input values. The main concept was to be able to use polling in order to
update the time. This method is superior to the previous usleep function because it is able to
handle other task before polling again to check for a timeout. In implementing the usleep
function the processor would not be able to complete other tasks. It also introduced the timer
which if set up properly it can be used as an interrupt to produce better performance

Edgar Siles
Instruction Timing NiosII System (Hardware/Software)
SYSTEM INFORMATION
System clock: 50 MHz
System components:
Processor: NiosII
Version and features: NiosII/s RISC: Instruction cache: Branch prediction:
Hardware multiply: Hardware divide
Instruction cache: Yes: 4K
Data cache: Yes: 2k
Debugging facility: Level 1, software breakpoints
Reset vector memory: sram_tristate_controller_0.uas
Reset vector offset: 0x00000000
Reset vector: 0x01840000
Exception vector memory: sram_tristate_controller_0.uas
Exception vector offset: 0x00000020
Exception vector: 0x01840020
Memory:
Type: RAM Writable [On Chip]
Data width: 32 Bit
Address width: 32K x 15
Size: 32K x 32
Read latency: Slave S1, S2 latency 1
Type: FLASH
Data width: 8 Bit
Address width: 22
Size: 4Mx8
Read latency: latency 2
Byteenable: 1
Bytes per word: 1
Avalon Interface: Readdata, writedata, read, write, chipselect, address
Signal Timing: Read wait: 90 Write wait:90 Set up:5 Hold:5 Turnaround: 2
Pending read transactions: 3 [All units in nanoseconds]
Type: SRAM
Data width: 16 Bit
Address width: 18
Size: 256K x 16
Read latency: latency 2
Byteenable: 2
Bytes per word: 2
Avalon Interface:Readdata, writedata, read, write, chipselect, address,byteenable

Signal Timing: Read wait: 20 Write wait:15 Set up:5 Hold:5 Turnaround: 2
Pending read transactions: 3 [All units in nanoseconds]
Peripheral components:
MASTER
Nios2_qsys_0
SLAVES
Interrupt level: nios2_qsys_0 IRQ base: 0 | jtag_uart_0 IRQ: 2
JTAG timer:
Write [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
Read [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
System ID Parameter: 1
Parallel PIO:
7-Segment: {High and Low, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 7
Buttons: {High and Low, INPUT}
Output bits: 2
Interval Timer:
Period: 1 microsecond (s)
Count size: 32
Preset: Interrupt
SETS: ONLY Fixed period, No Start/Stop control bits.
Linker segment mappings:
This is the diagram of where the design is stored with in the FPGA.

System memory map:

These are the addresses where each component of the design is located within the memory.
They represent the system.h base addresses.

BDF SYSTEM DIAGRAM


Top level design:

Qsys SYSTEM DIAGRAM


Qsys diagram:

This represents the inner connections of the design, with in the FPGA. It illustrates how the
peripherals are connected, and the master slave relations with in the design. The base addresses
are also assigned here and the reset and clock inputs to which the design will run.
CODE PROGRAM
C code:

/*
Lab 6
This lab is used to incorporate external memories such as the ROM and RAM and measure their response time
when used in certain ways. It will implement the use of a custom instruction and test its timing properties
in comparison to generic code. We are to learn to implement custom components, the PLL and test their
functionality
on the board. To do this we will store values in ROM and FLASH and call them to the seven-seg led's, measuring
the time it takes to implement using the custom instruction and generic code.
*/
#include<stdio.h>
#include"alt_types.h"
#include"altera_avalon_pio_regs.h"
#include"sys/alt_stdio.h"
#include"system.h"
#include<sys/alt_timestamp.h>

int main()
{
//Declare Variables
int k,j,done,f_c,flash_num_ones,flash_num_tens;
alt_u32 t0,t1,overhead;
//Initialize variables
k=0;j=0;done=0;t0=0;t1=0;
//Place all the variables in ROM
while(j<1000)//1000 mem locations
{
if(k == 100)
{
k=0;
}
IOWR(SDRAM_0_BASE,j,k);//write to ROM
k++;
j++;
}
//Flash Read c code implementation
k=0;
j=0;
alt_timestamp_start();
t0 = alt_timestamp();
t1 = alt_timestamp();
overhead=t1-t0;
alt_timestamp_start();//Reset time stamp
t0 = alt_timestamp();
while(done == 0)//Reached the end of the data
{
//Reads the Flash and places the data in a variable
f_c = IORD(FLASH_TRISTATE_CONTROLLER_0_BASE+k,0);
k++;//increases the location in the memory
flash_num_ones = f_c/10;
flash_num_tens = f_c-(f_c/10)*10;//y = X-(X/n)*n X MOD N
//Write numbers to 7-segments

IOWR(TWO_SEVEN_SEG_PIO_BASE ,0,svn_seg_decoder(flash_num_tens) &


svn_seg_decoder(flash_num_ones));
if(k == 1000 )//Checks for the end read
{
done=1;//Flag stating done with the display part
k = 0;//Resets time interval
}
}
t1 = alt_timestamp();
printf("The time for flash execution C-code is %u ms \n",(unsigned int)((t1-t0overhead)*1000/alt_timestamp_freq()));///alt_timestamp_freq()
printf ("time in ticks = %u \n",(unsigned int) (t1 - t0));
//printf ("Number of ticks per second = %u\n",(unsigned int)alt_timestamp_freq());
done=0;
alt_timestamp_start();//Reset time stamp
t0 = alt_timestamp();
//Custom Instruction Flash Read
while(done == 0)//Reached the end of the data per line
{
//Reads the Flash and places the data in a variable
f_c = IORD(FLASH_TRISTATE_CONTROLLER_0_BASE+k,0);
k++;//increases the location in the memory
//Write numbers to 7-segments
IOWR(ALT_CI_BIN32_TO_2SEVENSEG_0_N,0,f_c);
if(k == 1000 )//Checks for the end read
{
done=1;//Flag stating done with the display part
k = 0;//Resets time interval
}
}
t1 = alt_timestamp();
printf("The time for flash execution Custom instruction is %u ms \n",(unsigned int)((t1-t0overhead)*1000/alt_timestamp_freq()));///alt_timestamp_freq()
printf ("Time in ticks = %u \n",(unsigned int) (t1 - t0));
//printf ("Number of ticks per second = %u\n",(unsigned int)alt_timestamp_freq());
done=0;
k=0;
alt_timestamp_start();//Reset time stamp
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//SDRAM Read c code implementation
t0 = alt_timestamp();
while(done == 0)//Reached the end of the data
{
//Reads the Flash and places the data in a variable
f_c = IORD(SDRAM_0_BASE,k);
k++;//increases the location in the memory
flash_num_ones = f_c/10;
flash_num_tens = f_c-(f_c/10)*10;//y = X-(X/n)*n X MOD N
//Write numbers to 7-segments
IOWR(TWO_SEVEN_SEG_PIO_BASE,0,(svn_seg_decoder(flash_num_tens) &
svn_seg_decoder(flash_num_ones)));
if(k == 1000 )//Checks for the end read
{

done=1;//Flag stating done with the display part


k = 0;//Resets time interval
}
}
t1 = alt_timestamp();
printf("The time for SDRAM execution C-code is %u ms \n",(unsigned int)((t1-t0overhead)*1000/alt_timestamp_freq()));///alt_timestamp_freq()
printf ("Time in ticks = %u \n",(unsigned int) (t1 - t0));
//printf ("Number of ticks per second = %u\n",(unsigned int)alt_timestamp_freq());
done=0;
alt_timestamp_start();//Reset time stamp
t0 = alt_timestamp();
//SDRAM Read custom instruction
while(done == 0)//Reached the end of the data per line
{
//Reads the Flash and places the data in a variable
f_c = IORD(SDRAM_0_BASE,k);
k++;//increases the location in the memory
//Write numbers to 7-segments
IOWR(ALT_CI_BIN32_TO_2SEVENSEG_0_N,0,f_c);
if(k == 1000 )//Checks for the end read
{
done=1;//Flag stating done with the display part
k = 0;//Resets time interval
}
}
t1 = alt_timestamp();
printf("The time for SDRAM execution Custom instruction is %u ms \n",(unsigned int)((t1-t0overhead)*1000/alt_timestamp_freq()));///alt_timestamp_freq()
printf ("Time in ticks = %u \n",(unsigned int) (t1 - t0));
printf ("Number of ticks per second = %u\n",(unsigned int)alt_timestamp_freq());
alt_timestamp_start();//Reset time stamp
return 0;
}
int svn_seg_decoder(int a)
{
//The 7-Seg. decoder to display the proper number Look Up Table [LUT]
//Low lights up the 7-Seg.
/* 0
5| 6 |1
4| _ |2
3
bit # ordering = 6543210 or gfedcba
*/
int out[10] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x18 };
return out[a];
}

PROGRAM OUTCOME
Output:

FIG. 1 Output results

FIG. 2 Timer set up

DISCCISION/CONCLUSION
As it is shown, the program works as desired with the proper output to input
combinations. FIG 1 shows how the timestamp timer works. The program allows us to draw two
conclusions. One is that the custom instruction is almost 10 times faster than the c-code
instructions. The second is that the SDRAM is also faster than the FLASH memory in reading
time. The issue with this design came when the timer was being used as the system clock and the
time stamp. It was not know that the timer can only be used as one of the two selections, FIG. 2
illustrates the proper setup. The last thing that was noted is the way the custom instruction is set
up under the system.h. To know the proper way to call for the base address we had to go into the
system.h file in eclipse and see the name it was given.
The main concept was to be able to measure instruction times using the timestamp feature
of the timer. One other goal was also to prove that custom instructions are have a faster
execution time than C-code within the FPGA. It correlates to the hardware versus software
implementations. In the results of this experiment it is seen that the custom instructions are
indeed faster in execution time. The final goal of the laboratory experiment was to learn to use
the timestamp feature of the timer which counts the number of ticks in a sampled amount of
executions, which can then be turned into a measure of time. This can be accomplished by taking

an initial reading of the timer clicks, before the code to be executed, and a second reading at the
end. These clicks are then subtracted from each other, final time minus initial, and then subtract
the amount of click it take the processor to execute the instructions themselves{overhead}. All is
then divided by the timestamp frequency, which will then result in the amount of time it took to
execute the instruction. The unit of time will depend on the settings of the timer. The timestamp
uses unsigned integers so in order to mathematically manipulate we type cast. An example code
to measure the time in milliseconds (ms) is shown below.
(unsigned int)((t1-t0-overhead)*1000/alt_timestamp_freq()));

ROM Memory access


LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
LIBRARY lpm;
USE lpm.lpm_components.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY Hw3 IS
PORT(clk: IN STD_LOGIC;
RGB : OUT STD_LOGIC_VECTOR(8 DOWNTO 0);
HD_OUT , VD_OUT, DEN_OUT : OUT STD_LOGIC);
END Hw3;
ARCHITECTURE behavior OF Hw3 IS
------------------------------------SIGNALS---------------------------------------SIGNAL HD,VD : STD_LOGIC := '1';
SIGNAL TADD,iprow,ipcol : STD_LOGIC_VECTOR (11 DOWNTO 0) := (others => '0');
SIGNAL RGB0,RGB1,RGB2 : STD_LOGIC_VECTOR(8 DOWNTO 0);
--Controls the visible area
SIGNAL DEN, VvideoOn,HvideoOn, PLL_CLK : STD_LOGIC;
SIGNAL pcols : Integer range -1 to 799 :=-1;
SIGNAL prows : Integer range 0 to 479 :=0;
------------------------------------COMPONENTS---------------------------------------The Pll to create a 32.95 MHz clock
COMPONENT AL
PORT(inclk0 : IN STD_LOGIC;
c0
: OUT STD_LOGIC );
END COMPONENT;
--Rom where the pictures are stored
COMPONENT lpm_rom
GENERIC (LPM_WIDTH : integer; -- MUST be greater than 0
LPM_WIDTHAD : integer; -- MUST be greater than 0
LPM_FILE : string;
LPM_ADDRESS_CONTROL : string := "REGISTERED";
LPM_OUTDATA : string := "REGISTERED");
PORT (ADDRESS : in STD_LOGIC_VECTOR (LPM_WIDTHAD-1 downto 0);
inclock,outclock : IN STD_LOGIC;
Q : out STD_LOGIC_VECTOR (LPM_WIDTH-1 downto 0));
END COMPONENT;
BEGIN
------------------------------------PROCESS----------------------------------------

PROCESS(PLL_CLK)--PLL_CLK
--counters for the clks and generating signals
VARIABLE cnt_clk : INTEGER RANGE 0 TO 1056 :=0;
VARIABLE cnt_clk2 : INTEGER RANGE 0 TO 525 :=0;
VARIABLE H_cnt : INTEGER RANGE 0 TO 799 :=0;
VARIABLE V_cnt : INTEGER RANGE 0 TO 479 :=0;

BEGIN
IF(PLL_CLK'EVENT AND PLL_CLK='0')THEN--PLL_CLK
cnt_clk:= cnt_clk +1;
IF(cnt_clk=0)THEN
HD <= '0';
END IF;
IF(cnt_clk=1)THEN--H SYNCH ON
HD <= '1';
cnt_clk2 := cnt_clk2 +1;
END IF;
IF(cnt_clk=216)THEN--V VIDEO ON[216]
DEN <= '1';
HvideoOn <='1';
END IF;
IF(cnt_clk = 1016)THEN-- V VIDEO OFF[1016]
DEN <= '0';
HvideoOn <='0';
END IF;
IF(cnt_clk = 1056)THEN--[1056]
cnt_clk := 0;
HD <= '0';
END IF;
IF(cnt_clk2 = 0)THEN
VD <='0';
END IF;
IF(cnt_clk2 =1)THEN
VD <= '1';
END IF;
IF(cnt_clk2 = 35)THEN--[35]
VvideoOn<='1';
END IF;
IF(cnt_clk2 = 515)THEN--[515]
VvideoOn <= '0';
END IF;
IF(cnt_clk2 = 526)THEN--[525]
cnt_clk2 := 0;
END IF;
------------------------------------INSIDE THE CLK-----------------------------------------Prow and pcol counter for visable area
IF(HvideoOn='1' AND VvideoOn='1')THEN
pcols<=pcols+1;

IF(pcols=799)THEN
prows<=prows+1;
pcols<=0;
--resets the count when it reaches the end of the screen
ELSIF(prows=479)THEN
prows<=prows+1;
prows<=0;
END IF;
--Display area for first 2 pictures
IF(prows>=0 AND prows<=64)THEN
IF(pcols>=0 AND pcols<=64)THEN--0-64
TADD<=CONV_STD_LOGIC_VECTOR(pcols+(prows*16),12);
RGB<=RGB0;
END IF;
IF(pcols>=735 AND pcols<=799)THEN--735-799
TADD<=CONV_STD_LOGIC_VECTOR((pcols-735)+(prows*16),12);
RGB<=RGB1;
END IF;
END IF;
--Display area for last picture
IF(prows>=415 AND prows<=479)THEN
IF(pcols>=335 AND pcols<=399)THEN
TADD<=CONV_STD_LOGIC_VECTOR((pcols-735)+((prows415)*16),12);
RGB<=RGB2;
END IF;
END IF;
END IF;
--Output Synchronization Signals
HD_OUT<=HD;
VD_OUT<=VD;
DEN_OUT<=DEN;

END IF;--CLK
END PROCESS;
--PLL instantiation
inst_pll : AL PORT MAP(clk,PLL_CLK);
--Pictures in ROM
inst_ROM : lpm_rom
GENERIC MAP (LPM_WIDTH => 9, LPM_WIDTHAD => 12, LPM_FILE => "Car1.mif")
PORT MAP(ADDRESS=>TADD, inclock =>PLL_CLK, outclock=>PLL_CLK,Q=>RGB0);
inst_ROM1 : lpm_rom
GENERIC MAP (LPM_WIDTH => 9, LPM_WIDTHAD => 12, LPM_FILE => "camaro.mif")
PORT MAP(ADDRESS=>TADD, inclock =>PLL_CLK, outclock=>PLL_CLK,Q=>RGB1);

inst_ROM2 : lpm_rom
GENERIC MAP (LPM_WIDTH => 9, LPM_WIDTHAD => 12, LPM_FILE => "saleen.mif")
PORT MAP(ADDRESS=>TADD, inclock =>PLL_CLK, outclock=>PLL_CLK,Q=>RGB2);
END behavior;

These are the results obtain giving the proper values from the PLL.

Shows the overall process, CLK is at 33.2 MHz, CNT_CLK counts CLK, CNT_CLK2 Counts
when HD goes LOW and DEN is the data enable bit. Below is their timing executions.

Shows when the DEN Bit goes on according to the CNT_CLK count. [216]

Shows when the DEN Bit goes off according to the CNT_CLK count. [1016]

Shows when the HD Bit goes on according to the CNT_CLK count. [1057 or 1]. Because the system is
synchronous the resetting of it comes one clock latter but it has been fixed to fit the timing constrains,
meaning at count 1056 HD is still HIGH and when our count begins again at 1 the HD bit goes LOW.

This shows the proper value when the VD bit goes low. This is when an entire horizontal row
has been filled with the proper data it is now allowed to move on to the next row.

Shows the display region is being executed at the correct moment for the DEN, and correct clock
count

Displays the ending part of the row 1 with the changed values that were used for verification

MIF FILES

Edgar Siles
Interrupts NiosII System (Hardware/Software)
SYSTEM INFORMATION
System clock: 50 MHz
System components:
Processor: NiosII
Version and features: NiosII/s RISC: Instruction cache: Branch prediction:
Hardware multiply: Hardware divide
Instruction cache: Yes: 4K
Data cache: Yes: 2k
Debugging facility: Level 1, software breakpoints
Reset vector memory: onchip_memory2_0.s1
Reset vector offset: 0x00000000
Reset vector: 0x00080000
Exception vector memory: onchip_memory2_0.s1
Exception vector offset: 0x00000020
Exception vector: 0x00008020
Memory:
Type: RAM Writable [On Chip]
Data width: 32 Bit
Address width: 32K x 15
Size: 32K x 32
Read latency: Slave S1, S2 latency 1
Type: FLASH
Data width: 8 Bit
Address width: 22
Size: 4Mx8
Read latency: latency 2
Byteenable: 1
Bytes per word: 1
Avalon Interface: Readdata, writedata, read, write, chipselect, address
Signal Timing: Read wait: 90 Write wait:90 Set up:5 Hold:5 Turnaround: 2
Pending read transactions: 3 [All units in nanoseconds]
Type: SRAM
Data width: 16 Bit
Address width: 18
Size: 256K x 16
Read latency: latency 2
Byteenable: 2
Bytes per word: 2
Avalon Interface:Readdata, writedata, read, write, chipselect, address,byteenable

Signal Timing: Read wait: 20 Write wait:15 Set up:5 Hold:5 Turnaround: 2
Pending read transactions: 3 [All units in nanoseconds]
Peripheral components:
MASTER
Nios2_qsys_0
SLAVES
Interrupt level: nios2_qsys_0 IRQ base: 0 | jtag_uart_0 IRQ: 2
JTAG timer:
Write [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
Read [FIFO]:
IRQ threshold: 8
Buffer depth: 64 bytes
System ID Parameter: 1
Parallel PIO:
7-Segment: {High and Low, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 7
Buttons: {High and Low, INPUT}
Output bits: 2
LEDs: {8 Green LEDs, OUTPUT}
Output port reset value: 0x0000000000000000
Output bits: 8
LCD Display: {OUTPUT}
Optrex 16207 16x2 Character LCD panel
Interval Timer:
Period: 1 second
Count size: 32
Preset: Interrupt
SETS: ONLY Fixed period, No Start/Stop control bits.

Linker segment mappings:


This is the diagram of where the design is stored with in the FPGA.

System memory map:


These are the addresses where each component of the design is located within the memory.
They represent the system.h base addresses.

BDF SYSTEM DIAGRAM


Top level design:

Qsys SYSTEM DIAGRAM


Qsys diagram:

This represents the inner connections of the design, with in the FPGA. It illustrates how the

peripherals are connected, and the master slave relations with in the design. The base addresses
are also assigned here and the reset and clock inputs to which the design will run.
CODE PROGRAM
C code:
Lab 5 : Nios Introduction and initial procedures.
This is a program to have counters which will be used as a military time watch display.
It will make use of the :TIMER: to count for time by using its interrupt function.
For the timer function, it waits for the amount of microseconds placed in the function set the flag and
since we are interrupting it will then increase the sec. It will also make use of some of the on board switches
to modify the output to use the 7-Segment, LED's and monitor and LCD display, as visual displays, flash memory to
hold characters
and finally the RAM memory to store our system. Initially LED's-Off,
7-Seg.-00, and initial time is 00:00:00 It will also allow user input depending on the button selection.
Example: 23:59:59*/
#include<stdio.h>
#include<unistd.h>
#include"alt_types.h"
#include"altera_avalon_pio_regs.h"
#include"sys/alt_irq.h"
#include"system.h"
//Define the base address location of the peripherals
#define LCD_COMMAND_REG_WR 0
#define LCD_DATA_REG_WR 2
#define LCD_DATA_REG_RD 3
#define TIME_INTERVAL 5
int svn_seg_decoder(int a)
{
//The 7-Seg. decoder to display the proper number LUT
//Low lights up the 7-Seg.
/* 0
5| 6 |1
4| _ |2
3
bit # ordering = 6543210 or gfedcba
*/
int out[10] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x18 };
return out[a];
}
//The interrupt routine :){I got it}
static void handdle_timer_isr(int *sec_p, alt_u32 id)
{
*sec_p= *sec_p + 1; //Increase Timer
IOWR(TIMER_BASE,0,0);//Clear flag
}
static void lcd_display_fun(int R, int D)

{
//Function to write to the LCD any integer "D" at location"R"
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, R);
usleep(40);//40 us wait
IOWR(LCD_DISPLAY_BASE, LCD_DATA_REG_WR, (char)D+'0');
usleep(40);//40 us wait
}
static void lcd_display_fun_c(int Reg, char Data)
{
//Function to write to the LCD any character "DATA" at location"REG"
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, Reg);
usleep(40);//40 us wait
IOWR(LCD_DISPLAY_BASE, LCD_DATA_REG_WR, Data);
usleep(40);//40 us wait
}
static void lcd_display_colon(int RC)
{
//Function to write to the LCD The colon
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, RC);
usleep(40);//40 us wait
IOWR(LCD_DISPLAY_BASE, LCD_DATA_REG_WR, ':');
usleep(40);//40 us wait
}
int main()
{
//Declare variables
int sec1,sec2,min1,min2,hr1,hr2,cur_s,flg,done,add,cnt_time;
char h1,h2,m1,m2,s1,s2,ram_c1,ram_c2;
int *sec_p = &sec1;//pointer to pass to isr
*sec_p = 0;
//Initiate variables
sec1=0;min1=0;hr1=0;sec2=0;min2=0;hr2=0;
cur_s=0;flg=0x00;done=0;add=0x00;cnt_time=1;
//Calculate time
//Set function code 4 times--8 bit, 2 line, 5x7 mode
IOWR(LCD_DISPLAY_BASE,LCD_COMMAND_REG_WR,0x38);
usleep(4100);//4.1 ms wait
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x38);
usleep(100);//4.1 ms wait
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x38);
usleep(100);//4.1 ms wait
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x38);
usleep(100);//4.1 ms wait
//Display off
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x08);
usleep(40);//40 us wait
//Display on
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x0C);
usleep(40);//40 us wait
//Set entry mode, cursor increment,no display shift
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x06);
usleep(40);//40 us wait

//Clear the display


IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x01);
usleep(15200);//15.2 ms wait
//Interrupt
IOWR(TIMER_BASE,1,0x00000007);//Initiate the Timer LOCAL INTERRUPT
IOWR(TIMER_BASE,0,0);//Clear the interrupt flag
//Register the interrupt
alt_irq_register(TIMER_IRQ, sec_p, handdle_timer_isr);
while(1)
{
if((cur_s + 1) == sec1)//Checks for time increase{Interrupt occurred}
{
cur_s = sec1;//Increase time for following interrupt
cnt_time++;//update read interval time
//Timer will run here to increment the seconds therefore the time
if(sec1==10)//Checks for sec to increase ones place
{
sec2++;
sec1=0;
cur_s = 0;
}
if(sec2==6)//Checks for sec to increase tens place
{
min1++;
sec2=0;
}
if(min1==10)//Checks for min to increase ones place
{
min2++;
min1=0;
}
if(min2==6)//Checks for min to increase hr and tens place
{
hr1++;
min2=0;
}
if(hr1==10)//Checks for clock reset and repeat
{
hr2++;
hr1=0;
}
if(hr2==2 && hr1==4)//Checks for clock reset and repeat
{
hr2=0;
hr1=0;
}
switch(IORD_8DIRECT(BUTTON_PIO_BASE,0))
{
case 1:
//01 monitor display[seconds]
//Function to write to 7-Seg the proper number[seconds]
IOWR(SEVEN_SEG_LOW_PIO_BASE,0,svn_seg_decoder(sec2));
IOWR(SEVEN_SEG_HIGH_PIO_BASE,0,svn_seg_decoder(sec1));
//LED's unchanged

//Functions to write time to the LCD


IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x01);
usleep(15200);//15.20 ms wait
lcd_display_fun(0x84,hr2);
lcd_display_fun(0x85,hr1);
lcd_display_colon(0x86);
lcd_display_fun(0x87,min2);
lcd_display_fun(0x88,min1);
lcd_display_colon(0x89);
lcd_display_fun(0x8A,sec2);
lcd_display_fun(0x8B,sec1);
break;
case 2:
//10 monitor display [minutes]
//Function to write to the LCD
IOWR(LCD_DISPLAY_BASE, LCD_COMMAND_REG_WR, 0x01);
usleep(15200);//15.20 ms wait
lcd_display_fun(0x84,hr2);
lcd_display_fun(0x85,hr1);
lcd_display_colon(0x86);
lcd_display_fun(0x87,min2);
lcd_display_fun(0x88,min1);
lcd_display_colon(0x89);
lcd_display_fun(0x8A,sec2);
lcd_display_fun(0x8B,sec1);
break;
case 3:
//11 monitor display [hr min sec] for functionality
alt_printf("%c%c:%c%c:%c%c
\n",(char)hr2+'0',(char)hr1+'0',(char)min2+'0',(char)min1+'0',(char)sec2+'0',(char)sec1+'0');
//Function to write to 7-Seg the proper number[seconds]
IOWR(SEVEN_SEG_LOW_PIO_BASE,0,svn_seg_decoder(sec2));
IOWR(SEVEN_SEG_HIGH_PIO_BASE,0,svn_seg_decoder(sec1));
//Function to write to LED's the proper number[seconds]
IOWR(LED_PIO_BASE,0,((sec2*10)+sec1));
//Function to write to the LCD
lcd_display_fun(0x84,0);
lcd_display_fun(0x85,0);
lcd_display_colon(0x86);
lcd_display_fun(0x87,0);
lcd_display_fun(0x88,0);
lcd_display_colon(0x89);
lcd_display_fun(0x8A,sec2);
lcd_display_fun(0x8B,sec1);
if(cnt_time == TIME_INTERVAL)//time to change the Flash read
while(done == 0)//Reached the end of the data per line
{
//Reads the ram and places the data in a variable
ram_c1 = IORD_8DIRECT(FLASH_TRISTATE_CONTROLLER_0_BASE+flg+add,0);
++flg;//increases the location in the memory and the LCD display
ram_c2 = IORD_8DIRECT(FLASH_TRISTATE_CONTROLLER_0_BASE+flg+add,0);
++flg;
if(ram_c1 == 0x00 || ram_c2 == 0x00)//Checks for EOF

{
add = 0x00;//Resets the address for the rom read
flg = 0x00;//Resets the position of the specific address
done=1;//Flag stating done with the display part
cnt_time = 0;//Resets time interval
}
else if(ram_c1 == 0x0D || ram_c2 == 0x0D)//End of line
{
flg = 0x00;//Resets the position of the specific address
done=1;//Flag stating done with the display part
add = add + 0x10;//Increases the address for the rom read
cnt_time = 0;//Resets time interval
}
else
{
lcd_display_fun_c((0xC0+flg-1),ram_c1);//Displays the character from rom
lcd_display_fun_c((0xC0+flg),ram_c2);
}
}
else if(cnt_time > TIME_INTERVAL)//Resets the interval timing when coming
back from a different selection
cnt_time = 0;
done=0;//Resets the display rom flag for the next interrupt
break;
}
//Display results for change time option
if(IORD_8DIRECT(BUTTON_PIO_BASE,0)==0)
{
//Change time, No display LCD, LED's off and 7-Seg. 00
//Input the time. User input section for hr, min and sec.
alt_printf("Enter the hour's first digit #0:00:00, ");
alt_printf("Press ENTER when input is complete: ");
h2 = alt_getchar();
hr2=(int)h2-'0';
while ((h2 != '\n'))
h2 = alt_getchar();
alt_printf("Enter the hour's Second digit 0#:00:00, ");
alt_printf("Press ENTER when input is complete: ");
h1 = alt_getchar();
hr1=(int)h1-'0';
while ((h1 != '\n'))
h1 = alt_getchar();
alt_printf("Enter the minutes fist digit 00:#0:00, ");
alt_printf("Press ENTER when input is complete: ");
m2 = alt_getchar();
min2=(int)m2-'0';
while ((m2 != '\n'))
m2 = alt_getchar();
alt_printf("Enter the minutes second digit 00:0#:00, ");
alt_printf("Press ENTER when input is complete: ");
m1 = alt_getchar();
min1=(int)m1-'0';
while (m1 != '\n')
m1 = alt_getchar();
alt_printf("Enter the seconds fist digit 00:00:#0, ");
alt_printf("Press ENTER when input is complete: ");

s2 = alt_getchar();
sec2=(int)s2-'0';
while ((s2 != '\n'))
s2 = alt_getchar();
alt_printf("Enter the seconds second digit 00:00:0#, ");
alt_printf("Press ENTER when input is complete: ");
s1 = alt_getchar();
sec1=(int)(s1)-'0';
while (s1 != '\n')
s1 = alt_getchar();
//Turn off 7-Seg.
//Turn off LED's, Write 0's to LED's
//No monitor display
//Function to write clear the LCD
}
}
}
return 0;
}

PROGRAM OUTCOME
Output:
Monitor Display:
LED Display: ON 7-Seg. Display: ON Switch Positions: 00

LED Display: OFF 7-Seg. Display: ON Switch Positions: 01

LED Display: ON 7-Seg. Display: ON Switch Positions: 10

LED Display: ON 7-Seg. Display: ON Switch Positions: 11

FIG 1
DISCCISION/CONCLUSION
As it is shown, the program works as desired with the proper output to input
combinations. FIG 1 shows how the user input is accepted and correctly placed in the proper
variables in the system and the roll-over of the time to the desires specifications with their
respective button selection. The issue with this design comes when the user decides the input.
The design has a 5 second delay to display the results, in the delay time it is properly
functioning; therefore it solely applies to the display.
The main concept was to be able to use interrupts in order to update the time and be able
to use the flash memory. This method is superior to the previous polling method because it is
able to handle other task before an interrupt occurs again to check for a timeout. In implementing
the polling function the processor would be able to complete other tasks, but keep using
resources since it will be polling every clock cycle. This allows for a better performance design.
In using the flash, the design incorporated the custom gui DE2 control design that allows for
custom initialization and testing parameters.

Você também pode gostar