--testbench for http://scott2595.blogspot.com/2014/02/vhdl-code-for-serial-interface.html
library ieee;
use ieee.std_logic_1164.all;
use std.env.all;
use ieee.math_real.all;
use ieee.numeric_std.all;
--library gate_work;
--use gate_work.top;
entity tb_spi is
end entity tb_spi;
architecture behavioral of tb_spi is
component top is
port (
clk : in std_logic;
rst_n : in std_logic;
load : in std_logic;
slv_sel : in std_logic_vector(1 downto 0);
din : in std_logic_vector(4 downto 0);
led0 : out std_logic_vector(4 downto 0);
led1 : out std_logic_vector(4 downto 0);
led2 : out std_logic_vector(4 downto 0)
);
end component;
signal clk : std_logic;
signal rst_n : std_logic;
signal load : std_logic;
signal slv_sel : std_logic_vector(1 downto 0);
signal din : std_logic_vector(4 downto 0);
signal led0 : std_logic_vector(4 downto 0);
signal led1 : std_logic_vector(4 downto 0);
signal led2 : std_logic_vector(4 downto 0);
begin
u_top: top port map (
clk => clk ,
rst_n => rst_n ,
load => load ,
slv_sel => slv_sel ,
din => din ,
led0 => led0 ,
led1 => led1 ,
led2 => led2
);
process
begin
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
end process;
process
begin
rst_n <= '1';
wait for 100 ns;
rst_n <= '0';
wait for 100 ns;
rst_n <= '1';
wait;
end process;
process
variable seed1, seed2: positive;
variable int_rand: integer;
variable rand: real;
variable i: integer;
begin
seed1 := 1;
seed2 := 2;
load <= '0';
slv_sel <= "00";
din <= "00000";
wait for 300 ns;
wait until rising_edge(clk);
for i in 1 to 3 loop
uniform(seed1, seed2, rand);
int_rand := integer(trunc(rand * 31.0));
din <= std_logic_vector(to_unsigned(int_rand, din'length));
slv_sel <= std_logic_vector(to_unsigned(i, slv_sel'length));
wait until rising_edge(clk);
load <= '1';
wait until rising_edge(clk);
wait until rising_edge(clk);
load <= '0';
wait for 300 ns;
end loop;
finish(0);
end process;
end behavioral;
Tuesday, February 25, 2014
Monday, February 24, 2014
run modelsim in cmd mode
1) run script:
#!/bin/bash
if [ -e wave.wlf ]; then
rm -rf wave.wlf
fi
if [ ! -e work ]; then
vlib work
fi
vmap work work
vcom spi.vhd tb_spi.vhd
#vsim work.tb_spi -gui -do do.tcl -wlf wave.wlf
vsim work.tb_spi -c -do do.tcl -wlf wave.wlf
#!/bin/bash
if [ -e wave.wlf ]; then
rm -rf wave.wlf
fi
if [ ! -e work ]; then
vlib work
fi
vmap work work
vcom spi.vhd tb_spi.vhd
#vsim work.tb_spi -gui -do do.tcl -wlf wave.wlf
vsim work.tb_spi -c -do do.tcl -wlf wave.wlf
2) do.tcl:
add wave -r /*
run -all
exit
2) run script for running with coverage:
#!/bin/bash
if [ -e wave.wlf ]; then
rm -rf wave.wlf
fi
if [ -e work ]; then
rm -rf work
fi
vlib work
vmap work work
vcom +cover=sbceft counter.vhd tb_counter.vhd
vsim work.tb_counter -coverage -c -do do.tcl -wlf wave.wlf
2) run script for running with coverage:
#!/bin/bash
if [ -e wave.wlf ]; then
rm -rf wave.wlf
fi
if [ -e work ]; then
rm -rf work
fi
vlib work
vmap work work
vcom +cover=sbceft counter.vhd tb_counter.vhd
vsim work.tb_counter -coverage -c -do do.tcl -wlf wave.wlf
some basic cpp syntax
1) simple example:
2) variable accessibility
3) constructor and deconstructor
4) dynamically allocate memory
5) inherent
/////////////////////////////////////////////
//base.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//base.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//polygon.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//polygon.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
.PHONY: clean all
all: clean a.out
clean:
rm -rf *.o *.out *.exe
a.out: base.o main.o polygon.o rectangle.o
g++ -o $@ $^
6) polymorphism
/////////////////////////////////////////////
//polygon.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//polygon.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//triangle.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//triangle.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
.PHONY: clean all
all: clean a.out
ifeq ($(USE_VIRTUAL),1)
CPPFLAGS = -DUSE_VIRTUAL
endif
clean:
rm -rf *.o *.out *.exe
a.out: main.o polygon.o rectangle.o triangle.o
g++ -o $@ $^
7) override
/////////////////////////////////////////////
//polygon.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//polygon.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//triangle.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//triangle.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
8) smart pointer
/////////////////////////////////////////////
//hasPtr.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//hasPtr.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
/////////////////////////////////////////////
//hasPtr.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//hasPtr.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//swap.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//swap.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
10) friend class
/////////////////////////////////////////////
//hasPtr.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//hasPtr.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//ptrOp.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//ptrOp.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
11) inline
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
21) vector
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#############################################
#Makefile
#############################################
#include <iostream>
using std::cout;
using std::endl;
class basePoint {
public:
void setPoint(int, int);
void display();
private:
int x;
int y;
};
void basePoint::setPoint(int x, int y) {
this->x = x;
this->y = y;
}
void basePoint::display() {
std::cout << x << " " << y << std::endl;
}
int main(int argc, char* argv[]) {
basePoint bp0;
basePoint *bp1 = new basePoint();
bp0.setPoint(1, 2);
bp1->setPoint(3, 4);
bp0.display();
bp1->display();
return 0;
}
using std::cout;
using std::endl;
class basePoint {
public:
void setPoint(int, int);
void display();
private:
int x;
int y;
};
void basePoint::setPoint(int x, int y) {
this->x = x;
this->y = y;
}
void basePoint::display() {
std::cout << x << " " << y << std::endl;
}
int main(int argc, char* argv[]) {
basePoint bp0;
basePoint *bp1 = new basePoint();
bp0.setPoint(1, 2);
bp1->setPoint(3, 4);
bp0.display();
bp1->display();
return 0;
}
2) variable accessibility
#include <iostream>
using std::cout;
using std::endl;
class base {
public:
base();
void set_data(int, int, int);
void clear_data();
void display();
int z;
protected:
int y;
private:
int x;
};
base::base() {
x = 0;
y = 0;
z = 0;
}
void base::set_data(int x, int y, int z) {
this->x = x;
this->y = y;
this->z = z;
}
void base::clear_data() {
x = 0;
y = 0;
z = 0;
}
void base::display() {
cout << x << " " << y << " " << z << endl;
}
class public_subclass : public base {
public:
public_subclass();
void set_data(int, int, int, int, int, int);
void clear_data();
void display();
int a;
protected:
int b;
private:
int c;
};
public_subclass::public_subclass() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void public_subclass::set_data(int a, int b, int c, int x, int y, int z) {
this->a = a;
this->b = b;
this->c = c;
//x of class base cannot be accessed
//this->x = x;
this->y = y;
this->z = z;
}
void public_subclass::clear_data() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void public_subclass::display() {
//x of class base cannot be accessed
//cout << a << " " << b << " " << c << " " << x << " " << y << " " << z << endl;
cout << a << " " << b << " " << c << " " << y << " " << z << endl;
}
class protected_subclass : protected base {
public:
protected_subclass();
void set_data(int, int, int, int, int, int);
void clear_data();
void display();
int a;
protected:
int b;
private:
int c;
};
protected_subclass::protected_subclass() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void protected_subclass::set_data(int a, int b, int c, int x, int y, int z) {
this->a = a;
this->b = b;
this->c = c;
//x of class base cannot be accessed
//this->x = x;
this->y = y;
this->z = z;
}
void protected_subclass::clear_data() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void protected_subclass::display() {
//x of class base cannot be accessed
//cout << a << " " << b << " " << c << " " << x << " " << y << " " << z << endl;
cout << a << " " << b << " " << c << " " << y << " " << z << endl;
}
class private_subclass : private base {
public:
private_subclass();
void set_data(int, int, int, int, int, int);
void clear_data();
void display();
int a;
protected:
int b;
private:
int c;
};
private_subclass::private_subclass() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void private_subclass::set_data(int a, int b, int c, int x, int y, int z) {
this->a = a;
this->b = b;
this->c = c;
//x of class base cannot be accessed
//this->x = x;
this->y = y;
this->z = z;
}
void private_subclass::clear_data() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void private_subclass::display() {
//x of class base cannot be accessed
//cout << a << " " << b << " " << c << " " << x << " " << y << " " << z << endl;
cout << a << " " << b << " " << c << " " << y << " " << z << endl;
}
int main(int argc, char* argv[]) {
base u_base;
public_subclass u_public_subclass;
protected_subclass u_protected_subclass;
private_subclass u_private_subclass;
u_base.set_data(1, 2, 3);
u_base.display();
/////////////////////////////////////////////////
//x and y of class base cannot be accessed
/////////////////////////////////////////////////
//u_base.x = 10;
//u_base.y = 20;
u_base.z = 30;
u_base.display();
u_base.clear_data();
u_base.display();
/////////////////////////////////////////////////
//public base class
/////////////////////////////////////////////////
u_public_subclass.z = 21;
u_public_subclass.a = 22;
//b and c cannot be accessed
//u_public_subclass.b = 23;
//u_public_subclass.c = 24;
u_public_subclass.display();
/////////////////////////////////////////////////
//protected base class
/////////////////////////////////////////////////
//z cannot be accessed
//u_protected_subclass.z = 31;
u_protected_subclass.a = 37;
u_protected_subclass.display();
u_protected_subclass.set_data(31, 32, 33, 34, 35, 36);
u_protected_subclass.display();
/////////////////////////////////////////////////
//private base class
/////////////////////////////////////////////////
//z cannot be accessed
//u_private_subclass.z = 41;
u_private_subclass.a = 47;
u_private_subclass.display();
u_private_subclass.set_data(41, 42, 43, 44, 45, 46);
u_private_subclass.display();
}
using std::cout;
using std::endl;
class base {
public:
base();
void set_data(int, int, int);
void clear_data();
void display();
int z;
protected:
int y;
private:
int x;
};
base::base() {
x = 0;
y = 0;
z = 0;
}
void base::set_data(int x, int y, int z) {
this->x = x;
this->y = y;
this->z = z;
}
void base::clear_data() {
x = 0;
y = 0;
z = 0;
}
void base::display() {
cout << x << " " << y << " " << z << endl;
}
class public_subclass : public base {
public:
public_subclass();
void set_data(int, int, int, int, int, int);
void clear_data();
void display();
int a;
protected:
int b;
private:
int c;
};
public_subclass::public_subclass() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void public_subclass::set_data(int a, int b, int c, int x, int y, int z) {
this->a = a;
this->b = b;
this->c = c;
//x of class base cannot be accessed
//this->x = x;
this->y = y;
this->z = z;
}
void public_subclass::clear_data() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void public_subclass::display() {
//x of class base cannot be accessed
//cout << a << " " << b << " " << c << " " << x << " " << y << " " << z << endl;
cout << a << " " << b << " " << c << " " << y << " " << z << endl;
}
class protected_subclass : protected base {
public:
protected_subclass();
void set_data(int, int, int, int, int, int);
void clear_data();
void display();
int a;
protected:
int b;
private:
int c;
};
protected_subclass::protected_subclass() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void protected_subclass::set_data(int a, int b, int c, int x, int y, int z) {
this->a = a;
this->b = b;
this->c = c;
//x of class base cannot be accessed
//this->x = x;
this->y = y;
this->z = z;
}
void protected_subclass::clear_data() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void protected_subclass::display() {
//x of class base cannot be accessed
//cout << a << " " << b << " " << c << " " << x << " " << y << " " << z << endl;
cout << a << " " << b << " " << c << " " << y << " " << z << endl;
}
class private_subclass : private base {
public:
private_subclass();
void set_data(int, int, int, int, int, int);
void clear_data();
void display();
int a;
protected:
int b;
private:
int c;
};
private_subclass::private_subclass() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void private_subclass::set_data(int a, int b, int c, int x, int y, int z) {
this->a = a;
this->b = b;
this->c = c;
//x of class base cannot be accessed
//this->x = x;
this->y = y;
this->z = z;
}
void private_subclass::clear_data() {
a = 0;
b = 0;
c = 0;
//x of class base cannot be accessed
//x = 0;
y = 0;
z = 0;
}
void private_subclass::display() {
//x of class base cannot be accessed
//cout << a << " " << b << " " << c << " " << x << " " << y << " " << z << endl;
cout << a << " " << b << " " << c << " " << y << " " << z << endl;
}
int main(int argc, char* argv[]) {
base u_base;
public_subclass u_public_subclass;
protected_subclass u_protected_subclass;
private_subclass u_private_subclass;
u_base.set_data(1, 2, 3);
u_base.display();
/////////////////////////////////////////////////
//x and y of class base cannot be accessed
/////////////////////////////////////////////////
//u_base.x = 10;
//u_base.y = 20;
u_base.z = 30;
u_base.display();
u_base.clear_data();
u_base.display();
/////////////////////////////////////////////////
//public base class
/////////////////////////////////////////////////
u_public_subclass.z = 21;
u_public_subclass.a = 22;
//b and c cannot be accessed
//u_public_subclass.b = 23;
//u_public_subclass.c = 24;
u_public_subclass.display();
/////////////////////////////////////////////////
//protected base class
/////////////////////////////////////////////////
//z cannot be accessed
//u_protected_subclass.z = 31;
u_protected_subclass.a = 37;
u_protected_subclass.display();
u_protected_subclass.set_data(31, 32, 33, 34, 35, 36);
u_protected_subclass.display();
/////////////////////////////////////////////////
//private base class
/////////////////////////////////////////////////
//z cannot be accessed
//u_private_subclass.z = 41;
u_private_subclass.a = 47;
u_private_subclass.display();
u_private_subclass.set_data(41, 42, 43, 44, 45, 46);
u_private_subclass.display();
}
3) constructor and deconstructor
//deconstructor of base class must be virtual function
#include <iostream>
using std::cout;
using std::endl;
class base {
public:
base();
virtual ~base();
};
base::base() {
}
base::~base() {
cout << "Calling deconstruction of base!" << endl;
}
class subclass : public base {
public:
subclass();
~subclass();
};
subclass::subclass() {
}
subclass::~subclass() {
cout << "Calling deconstruction of subclass!" << endl;
}
int main(int argc, char* argv[]) {
base *u_base = new subclass;
delete u_base;
return 0;
}
#include <iostream>
using std::cout;
using std::endl;
class base {
public:
base();
virtual ~base();
};
base::base() {
}
base::~base() {
cout << "Calling deconstruction of base!" << endl;
}
class subclass : public base {
public:
subclass();
~subclass();
};
subclass::subclass() {
}
subclass::~subclass() {
cout << "Calling deconstruction of subclass!" << endl;
}
int main(int argc, char* argv[]) {
base *u_base = new subclass;
delete u_base;
return 0;
}
4) dynamically allocate memory
#include <iostream>
//#include <cstddef>
#include <stddef.h>
using std::cout;
using std::endl;
using std::nothrow;
//using std::nullptr;
//using std::nullptr_t;
int main(int argc, char* argv[]) {
//will throw an error when memory cannot be allocated
int *var1 = new int[10];
//will not throw an error when memory cannot be allocated
int *var2 = new (nothrow) int [10];
//c++ 11
//if(var2 == nullptr) {
if(var2 == 0) {
cout << "Cannot allocate memory" << endl;
return 1;
}
for(int i=0; i<10; i++) {
*(var1 + i) = i;
*(var2 + i) = i + 10;
}
for(int i=0; i<10; i++) {
cout << *(var1 + i) << " " << *(var2 + i) << endl;
}
delete [] var1;
delete [] var2;
return 0;
}
//#include <cstddef>
#include <stddef.h>
using std::cout;
using std::endl;
using std::nothrow;
//using std::nullptr;
//using std::nullptr_t;
int main(int argc, char* argv[]) {
//will throw an error when memory cannot be allocated
int *var1 = new int[10];
//will not throw an error when memory cannot be allocated
int *var2 = new (nothrow) int [10];
//c++ 11
//if(var2 == nullptr) {
if(var2 == 0) {
cout << "Cannot allocate memory" << endl;
return 1;
}
for(int i=0; i<10; i++) {
*(var1 + i) = i;
*(var2 + i) = i + 10;
}
for(int i=0; i<10; i++) {
cout << *(var1 + i) << " " << *(var2 + i) << endl;
}
delete [] var1;
delete [] var2;
return 0;
}
5) inherent
/////////////////////////////////////////////
//base.h
/////////////////////////////////////////////
#ifndef __BASE_H__
#define __BASE_H__
#include <iostream>
using std::cout;
using std::endl;
class basePoint {
public:
basePoint();
basePoint(int, int);
virtual ~basePoint();
void setPoint(int, int);
void display();
private:
int x;
int y;
};
#endif
#define __BASE_H__
#include <iostream>
using std::cout;
using std::endl;
class basePoint {
public:
basePoint();
basePoint(int, int);
virtual ~basePoint();
void setPoint(int, int);
void display();
private:
int x;
int y;
};
#endif
/////////////////////////////////////////////
//base.cpp
/////////////////////////////////////////////
#ifndef __BASE_CPP__
#define __BASE_CPP__
#include "base.h"
basePoint::basePoint() {
x = 10;
y = 10;
}
basePoint::basePoint(int x, int y) {
this->x = x;
this->y = y;
}
basePoint::~basePoint() {
}
void basePoint::setPoint(int x, int y) {
this->x = x;
this->y = y;
}
void basePoint::display() {
std::cout << x << " " << y << " " << std::endl;
}
#endif
#define __BASE_CPP__
#include "base.h"
basePoint::basePoint() {
x = 10;
y = 10;
}
basePoint::basePoint(int x, int y) {
this->x = x;
this->y = y;
}
basePoint::~basePoint() {
}
void basePoint::setPoint(int x, int y) {
this->x = x;
this->y = y;
}
void basePoint::display() {
std::cout << x << " " << y << " " << std::endl;
}
#endif
/////////////////////////////////////////////
//polygon.h
/////////////////////////////////////////////
#ifndef __SUBCLASS_H__
#define __SUBCLASS_H__
#include <iostream>
#include "base.h"
using std::cout;
using std::endl;
class polygon {
public:
polygon();
polygon(int);
virtual ~polygon();
void display();
protected:
bool genPolygon();
private:
int pointNo;
basePoint **bp;
};
#endif
#define __SUBCLASS_H__
#include <iostream>
#include "base.h"
using std::cout;
using std::endl;
class polygon {
public:
polygon();
polygon(int);
virtual ~polygon();
void display();
protected:
bool genPolygon();
private:
int pointNo;
basePoint **bp;
};
#endif
/////////////////////////////////////////////
//polygon.cpp
/////////////////////////////////////////////
#ifndef __SUBCLASS_CPP__
#define __SUBCLASS_CPP__
#include "polygon.h"
polygon::polygon() {
pointNo = 10;
genPolygon();
}
polygon::polygon(int number) {
pointNo = number;
genPolygon();
}
polygon::~polygon() {
for(int i=0; i<pointNo; i++) {
delete bp[i];
}
delete [] bp;
}
bool polygon::genPolygon() {
bp = new basePoint*[pointNo];
for(int i=0; i<pointNo; i++) {
bp[i] = new basePoint();
}
return true;
}
void polygon::display() {
for(int i=0; i<pointNo; i++) {
cout << "Point: " << i << endl;
bp[i]->display();
}
}
#endif
#define __SUBCLASS_CPP__
#include "polygon.h"
polygon::polygon() {
pointNo = 10;
genPolygon();
}
polygon::polygon(int number) {
pointNo = number;
genPolygon();
}
polygon::~polygon() {
for(int i=0; i<pointNo; i++) {
delete bp[i];
}
delete [] bp;
}
bool polygon::genPolygon() {
bp = new basePoint*[pointNo];
for(int i=0; i<pointNo; i++) {
bp[i] = new basePoint();
}
return true;
}
void polygon::display() {
for(int i=0; i<pointNo; i++) {
cout << "Point: " << i << endl;
bp[i]->display();
}
}
#endif
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
#ifndef __RECTANGLE_H__
#define __RECTANGLE_H__
#include <iostream>
#include "polygon.h"
using std::cout;
using std::endl;
class rectangle : public polygon {
public:
rectangle();
virtual ~rectangle();
};
#endif
#define __RECTANGLE_H__
#include <iostream>
#include "polygon.h"
using std::cout;
using std::endl;
class rectangle : public polygon {
public:
rectangle();
virtual ~rectangle();
};
#endif
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
#ifndef __RECTANGLE_CPP__
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle() : polygon(4) {
}
rectangle::~rectangle() {
}
#endif
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle() : polygon(4) {
}
rectangle::~rectangle() {
}
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include "rectangle.h"
int main(int argc, char* argv[]) {
polygon poly;
poly.display();
rectangle *rect = new rectangle();
rect->display();
delete rect;
return 0;
}
int main(int argc, char* argv[]) {
polygon poly;
poly.display();
rectangle *rect = new rectangle();
rect->display();
delete rect;
return 0;
}
#############################################
#Makefile
#############################################
all: clean a.out
clean:
rm -rf *.o *.out *.exe
a.out: base.o main.o polygon.o rectangle.o
g++ -o $@ $^
6) polymorphism
/////////////////////////////////////////////
//polygon.h
/////////////////////////////////////////////
#ifndef __POLYGON_H__
#define __POLYGON_H__
#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
class polygon {
public:
polygon(int, int);
virtual ~polygon();
void display();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
int width;
int height;
};
#endif
#define __POLYGON_H__
#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
class polygon {
public:
polygon(int, int);
virtual ~polygon();
void display();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
int width;
int height;
};
#endif
/////////////////////////////////////////////
//polygon.cpp
/////////////////////////////////////////////
#ifndef __POLYGON_CPP__
#define __POLYGON_CPP__
#include "polygon.h"
polygon::polygon(int width, int height) {
this->width = width;
this->height = height;
}
polygon::~polygon() {
}
float polygon::area() {
return 0;
}
void polygon::display() {
cout << "width: " << width << " height: " << height << endl;
}
#endif
#define __POLYGON_CPP__
#include "polygon.h"
polygon::polygon(int width, int height) {
this->width = width;
this->height = height;
}
polygon::~polygon() {
}
float polygon::area() {
return 0;
}
void polygon::display() {
cout << "width: " << width << " height: " << height << endl;
}
#endif
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
#ifndef __RECTANGLE_H__
#define __RECTANGLE_H__
#include <iostream>
#include "polygon.h"
using std::cout;
using std::endl;
class rectangle : public polygon {
public:
rectangle(int, int);
virtual ~rectangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
};
#endif
#define __RECTANGLE_H__
#include <iostream>
#include "polygon.h"
using std::cout;
using std::endl;
class rectangle : public polygon {
public:
rectangle(int, int);
virtual ~rectangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
};
#endif
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
#ifndef __RECTANGLE_CPP__
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle(int width, int height) : polygon(width, height) {
}
rectangle::~rectangle() {
}
float rectangle::area() {
return width * height;
}
#endif
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle(int width, int height) : polygon(width, height) {
}
rectangle::~rectangle() {
}
float rectangle::area() {
return width * height;
}
#endif
/////////////////////////////////////////////
//triangle.h
/////////////////////////////////////////////
#ifndef __TRIANGLE_H__
#define __TRIANGLE_H__
#include <iostream>
#include "polygon.h"
using std::cout;
using std::endl;
class triangle : public polygon {
public:
triangle(int, int);
virtual ~triangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
};
#endif
#define __TRIANGLE_H__
#include <iostream>
#include "polygon.h"
using std::cout;
using std::endl;
class triangle : public polygon {
public:
triangle(int, int);
virtual ~triangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
};
#endif
/////////////////////////////////////////////
//triangle.cpp
/////////////////////////////////////////////
#ifndef __TRIANGLE_CPP__
#define __TRIANGLE_CPP__
#include "triangle.h"
triangle::triangle(int width, int height) : polygon(width, height) {
}
triangle::~triangle() {
}
float triangle::area() {
return float(width) * float(height) / 2;
}
#endif
#define __TRIANGLE_CPP__
#include "triangle.h"
triangle::triangle(int width, int height) : polygon(width, height) {
}
triangle::~triangle() {
}
float triangle::area() {
return float(width) * float(height) / 2;
}
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include "polygon.h"
#include "rectangle.h"
#include "triangle.h"
int main(int argc, char* argv[]) {
rectangle *rect = new rectangle(2, 3);
polygon *poly1 = new rectangle(2, 3);
cout << "Area of rectangle by calling the function area of rectangle: " << rect->area() << endl;
//if area is not virtual function, the return data will be 0
cout << "Area of rectangle by calling the function area of polygon: " << poly1->area() << endl;
triangle *tri = new triangle(2, 3);
polygon *poly2 = new triangle(2, 3);
cout << "Area of triangle by calling the function area of triangle: " << tri->area() << endl;
//if area is not virtual function, the return data will be 0
cout << "Area of triangle by calling the function area of polygon: " << poly2->area() << endl;
delete rect;
delete tri;
return 0;
}
#include "rectangle.h"
#include "triangle.h"
int main(int argc, char* argv[]) {
rectangle *rect = new rectangle(2, 3);
polygon *poly1 = new rectangle(2, 3);
cout << "Area of rectangle by calling the function area of rectangle: " << rect->area() << endl;
//if area is not virtual function, the return data will be 0
cout << "Area of rectangle by calling the function area of polygon: " << poly1->area() << endl;
triangle *tri = new triangle(2, 3);
polygon *poly2 = new triangle(2, 3);
cout << "Area of triangle by calling the function area of triangle: " << tri->area() << endl;
//if area is not virtual function, the return data will be 0
cout << "Area of triangle by calling the function area of polygon: " << poly2->area() << endl;
delete rect;
delete tri;
return 0;
}
#############################################
#Makefile
#############################################
all: clean a.out
ifeq ($(USE_VIRTUAL),1)
CPPFLAGS = -DUSE_VIRTUAL
endif
clean:
rm -rf *.o *.out *.exe
a.out: main.o polygon.o rectangle.o triangle.o
g++ -o $@ $^
7) override
/////////////////////////////////////////////
//polygon.h
/////////////////////////////////////////////
#ifndef __POLYGON_H__
#define __POLYGON_H__
#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
class polygon {
public:
polygon(int, int);
virtual ~polygon();
void display();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
int width;
int height;
};
#endif
#define __POLYGON_H__
#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
class polygon {
public:
polygon(int, int);
virtual ~polygon();
void display();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
int width;
int height;
};
#endif
/////////////////////////////////////////////
//polygon.cpp
/////////////////////////////////////////////
#ifndef __POLYGON_CPP__
#define __POLYGON_CPP__
#include "polygon.h"
polygon::polygon(int width, int height) {
this->width = width;
this->height = height;
}
polygon::~polygon() {
}
float polygon::area() {
return 0;
}
void polygon::display() {
cout << "width: " << width << " height: " << height << endl;
}
#endif
#define __POLYGON_CPP__
#include "polygon.h"
polygon::polygon(int width, int height) {
this->width = width;
this->height = height;
}
polygon::~polygon() {
}
float polygon::area() {
return 0;
}
void polygon::display() {
cout << "width: " << width << " height: " << height << endl;
}
#endif
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
#ifndef __RECTANGLE_H__
#define __RECTANGLE_H__
#include <iostream>
#include "polygon.h"
#include "triangle.h"
using std::cout;
using std::endl;
class triangle;
class rectangle : public polygon {
public:
rectangle(int, int);
virtual ~rectangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
float operator+(rectangle&);
#ifdef RECT_PLUS_TRI
float operator+(triangle&);
#endif
};
#endif
#define __RECTANGLE_H__
#include <iostream>
#include "polygon.h"
#include "triangle.h"
using std::cout;
using std::endl;
class triangle;
class rectangle : public polygon {
public:
rectangle(int, int);
virtual ~rectangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
float operator+(rectangle&);
#ifdef RECT_PLUS_TRI
float operator+(triangle&);
#endif
};
#endif
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
#ifndef __RECTANGLE_CPP__
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle(int width, int height) : polygon(width, height) {
}
rectangle::~rectangle() {
}
float rectangle::area() {
return width * height;
}
float rectangle::operator+(rectangle& rect) {
return this->area() + rect.area();
}
#ifdef RECT_PLUS_TRI
float rectangle::operator+(triangle& tri) {
return this->area() + tri.area();
}
#endif
#endif
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle(int width, int height) : polygon(width, height) {
}
rectangle::~rectangle() {
}
float rectangle::area() {
return width * height;
}
float rectangle::operator+(rectangle& rect) {
return this->area() + rect.area();
}
#ifdef RECT_PLUS_TRI
float rectangle::operator+(triangle& tri) {
return this->area() + tri.area();
}
#endif
#endif
/////////////////////////////////////////////
//triangle.h
/////////////////////////////////////////////
#ifndef __TRIANGLE_H__
#define __TRIANGLE_H__
#include <iostream>
#include "polygon.h"
#include "rectangle.h"
using std::cout;
using std::endl;
class rectangle;
class triangle : public polygon {
public:
triangle(int, int);
virtual ~triangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
float operator+(triangle&);
#ifdef TRI_PLUS_RECT
float operator+(rectangle&);
#endif
};
#endif
#define __TRIANGLE_H__
#include <iostream>
#include "polygon.h"
#include "rectangle.h"
using std::cout;
using std::endl;
class rectangle;
class triangle : public polygon {
public:
triangle(int, int);
virtual ~triangle();
#ifdef USE_VIRTUAL
virtual float area();
#else
float area();
#endif
float operator+(triangle&);
#ifdef TRI_PLUS_RECT
float operator+(rectangle&);
#endif
};
#endif
/////////////////////////////////////////////
//triangle.cpp
/////////////////////////////////////////////
#ifndef __TRIANGLE_CPP__
#define __TRIANGLE_CPP__
#include "triangle.h"
triangle::triangle(int width, int height) : polygon(width, height) {
}
triangle::~triangle() {
}
float triangle::area() {
return float(width) * float(height) / 2;
}
float triangle::operator+(triangle& tri) {
return this->area() + tri.area();
}
#ifdef TRI_PLUS_RECT
float triangle::operator+(rectangle& rect) {
return this->area() + rect.area();
}
#endif
#endif
#define __TRIANGLE_CPP__
#include "triangle.h"
triangle::triangle(int width, int height) : polygon(width, height) {
}
triangle::~triangle() {
}
float triangle::area() {
return float(width) * float(height) / 2;
}
float triangle::operator+(triangle& tri) {
return this->area() + tri.area();
}
#ifdef TRI_PLUS_RECT
float triangle::operator+(rectangle& rect) {
return this->area() + rect.area();
}
#endif
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include "polygon.h"
#include "rectangle.h"
#include "triangle.h"
int main(int argc, char* argv[]) {
rectangle *rect1 = new rectangle(2, 2);
cout << "Area of rect1angle by calling the function area of rect1angle: " << rect1->area() << endl;
rectangle *rect2 = new rectangle(3, 3);
cout << "Area of rectangle by calling the function area of rectangle: " << rect2->area() << endl;
cout << "Area of rect1 plus rect2 is: " << *rect1 + *rect2 << endl;
triangle *tri1 = new triangle(2, 2);
cout << "Area of triangle by calling the function area of triangle: " << tri1->area() << endl;
triangle *tri2 = new triangle(3, 3);
cout << "Area of triangle by calling the function area of triangle: " << tri2->area() << endl;
cout << "Area of tri1 plus tri2 is: " << *tri1 + *tri2 << endl;
#ifdef RECT_PLUS_TRI
cout << "Area of rect1 plus tri1 is: " << *rect1 + *tri1 << endl;
#endif
#ifdef TRI_PLUS_RECT
cout << "Area of tri1 plus rect1 is: " << *tri1 + *rect1 << endl;
#endif
delete rect1;
delete rect2;
delete tri1;
delete tri2;
return 0;
}
#include "rectangle.h"
#include "triangle.h"
int main(int argc, char* argv[]) {
rectangle *rect1 = new rectangle(2, 2);
cout << "Area of rect1angle by calling the function area of rect1angle: " << rect1->area() << endl;
rectangle *rect2 = new rectangle(3, 3);
cout << "Area of rectangle by calling the function area of rectangle: " << rect2->area() << endl;
cout << "Area of rect1 plus rect2 is: " << *rect1 + *rect2 << endl;
triangle *tri1 = new triangle(2, 2);
cout << "Area of triangle by calling the function area of triangle: " << tri1->area() << endl;
triangle *tri2 = new triangle(3, 3);
cout << "Area of triangle by calling the function area of triangle: " << tri2->area() << endl;
cout << "Area of tri1 plus tri2 is: " << *tri1 + *tri2 << endl;
#ifdef RECT_PLUS_TRI
cout << "Area of rect1 plus tri1 is: " << *rect1 + *tri1 << endl;
#endif
#ifdef TRI_PLUS_RECT
cout << "Area of tri1 plus rect1 is: " << *tri1 + *rect1 << endl;
#endif
delete rect1;
delete rect2;
delete tri1;
delete tri2;
return 0;
}
#############################################
#Makefile
#############################################
.PHONY: clean all
all: clean a.out
CPPFLAGS = -DUSE_VIRTUAL
ifeq (${RECT_PLUS_TRI}, 1)
CPPFLAGS += -DRECT_PLUS_TRI
endif
ifeq (${TRI_PLUS_RECT}, 1)
CPPFLAGS += -DTRI_PLUS_RECT
endif
clean:
rm -rf *.o *.out *.exe
a.out: main.o polygon.o rectangle.o triangle.o
g++ -o $@ $^
all: clean a.out
CPPFLAGS = -DUSE_VIRTUAL
ifeq (${RECT_PLUS_TRI}, 1)
CPPFLAGS += -DRECT_PLUS_TRI
endif
ifeq (${TRI_PLUS_RECT}, 1)
CPPFLAGS += -DTRI_PLUS_RECT
endif
clean:
rm -rf *.o *.out *.exe
a.out: main.o polygon.o rectangle.o triangle.o
g++ -o $@ $^
8) smart pointer
/////////////////////////////////////////////
//hasPtr.h
/////////////////////////////////////////////
#ifndef __HASPTR_H__
#define __HASPTR_H__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
#endif
#define __HASPTR_H__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
#endif
/////////////////////////////////////////////
//hasPtr.cpp
/////////////////////////////////////////////
#ifndef __HASPTR_CPP__
#define __HASPTR_CPP__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
HasPtr::HasPtr(const HasPtr &p): ps(p.ps), i(p.i), use(p.use) {
++*use;
}
HasPtr::~HasPtr() {
if (--*use == 0) {
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr &rhs) {
++*rhs.use;
if(--*use == 0) {
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
#endif
#define __HASPTR_CPP__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
HasPtr::HasPtr(const HasPtr &p): ps(p.ps), i(p.i), use(p.use) {
++*use;
}
HasPtr::~HasPtr() {
if (--*use == 0) {
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr &rhs) {
++*rhs.use;
if(--*use == 0) {
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include "hasPtr.h"
int main(int argc, char* argv[]) {
HasPtr *hasPtr1 = new HasPtr("string 1");
HasPtr *hasPtr2 = new HasPtr("string 2");
hasPtr1->display();
hasPtr2->display();
*hasPtr2 = *hasPtr1;
hasPtr1->display();
hasPtr2->display();
delete hasPtr1;
hasPtr2->display();
delete hasPtr2;
return 0;
}
int main(int argc, char* argv[]) {
HasPtr *hasPtr1 = new HasPtr("string 1");
HasPtr *hasPtr2 = new HasPtr("string 2");
hasPtr1->display();
hasPtr2->display();
*hasPtr2 = *hasPtr1;
hasPtr1->display();
hasPtr2->display();
delete hasPtr1;
hasPtr2->display();
delete hasPtr2;
return 0;
}
#############################################
#Makefile
#############################################
.PHONY: clean
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o hasPtr.o swap.o
g++ -o $@ $^
9) friend functionall: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o hasPtr.o swap.o
g++ -o $@ $^
/////////////////////////////////////////////
//hasPtr.h
/////////////////////////////////////////////
#ifndef __HASPTR_H__
#define __HASPTR_H__
#include <string>
#include <iostream>
#include "swap.h"
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
#endif
#define __HASPTR_H__
#include <string>
#include <iostream>
#include "swap.h"
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
#endif
/////////////////////////////////////////////
//hasPtr.cpp
/////////////////////////////////////////////
#ifndef __HASPTR_CPP__
#define __HASPTR_CPP__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
HasPtr::HasPtr(const HasPtr &p): ps(p.ps), i(p.i), use(p.use) {
++*use;
}
HasPtr::~HasPtr() {
if (--*use == 0) {
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr &rhs) {
++*rhs.use;
if(--*use == 0) {
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
#endif
#define __HASPTR_CPP__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
HasPtr::HasPtr(const HasPtr &p): ps(p.ps), i(p.i), use(p.use) {
++*use;
}
HasPtr::~HasPtr() {
if (--*use == 0) {
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr &rhs) {
++*rhs.use;
if(--*use == 0) {
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
#endif
/////////////////////////////////////////////
//swap.h
/////////////////////////////////////////////
#ifndef __SWAP_H__
#define __SWAP_H__
#include "hasPtr.h"
class HasPtr;
void swap(HasPtr&, HasPtr&);
#endif
#define __SWAP_H__
#include "hasPtr.h"
class HasPtr;
void swap(HasPtr&, HasPtr&);
#endif
/////////////////////////////////////////////
//swap.cpp
/////////////////////////////////////////////
#ifndef __SWAP_CPP__
#define __SWAP_CPP__
#include "swap.h"
void swap(HasPtr &lhs, HasPtr &rhs) {
using std::swap;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
}
#endif
#define __SWAP_CPP__
#include "swap.h"
void swap(HasPtr &lhs, HasPtr &rhs) {
using std::swap;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
}
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include <iostream>
#include "hasPtr.h"
#include "swap.h"
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
HasPtr *hasPtr1 = new HasPtr("string 1");
HasPtr *hasPtr2 = new HasPtr("string 2");
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
swap(*hasPtr1, *hasPtr2);
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
delete hasPtr1;
delete hasPtr2;
return 0;
}
#include "hasPtr.h"
#include "swap.h"
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
HasPtr *hasPtr1 = new HasPtr("string 1");
HasPtr *hasPtr2 = new HasPtr("string 2");
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
swap(*hasPtr1, *hasPtr2);
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
delete hasPtr1;
delete hasPtr2;
return 0;
}
#############################################
#Makefile
#############################################
.PHONY: clean
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o hasPtr.o swap.o
g++ -o $@ $^
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o hasPtr.o swap.o
g++ -o $@ $^
10) friend class
/////////////////////////////////////////////
//hasPtr.h
/////////////////////////////////////////////
#ifndef __HASPTR_H__
#define __HASPTR_H__
#include <string>
#include <iostream>
#include "ptrOp.h"
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend class ptrOp;
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
#endif
#define __HASPTR_H__
#include <string>
#include <iostream>
#include "ptrOp.h"
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend class ptrOp;
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
#endif
/////////////////////////////////////////////
//hasPtr.cpp
/////////////////////////////////////////////
#ifndef __HASPTR_CPP__
#define __HASPTR_CPP__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend class ptrOp;
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
HasPtr::HasPtr(const HasPtr &p): ps(p.ps), i(p.i), use(p.use) {
++*use;
}
HasPtr::~HasPtr() {
if (--*use == 0) {
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr &rhs) {
++*rhs.use;
if(--*use == 0) {
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
#endif
#define __HASPTR_CPP__
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class HasPtr {
friend class ptrOp;
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new std::size_t(1)) {}
HasPtr(const HasPtr &);
HasPtr& operator=(const HasPtr&);
~HasPtr();
void display() {
cout << "ps: " << *ps << " use: " << *use << endl;
}
private:
std::string *ps;
int i;
std::size_t *use;
};
HasPtr::HasPtr(const HasPtr &p): ps(p.ps), i(p.i), use(p.use) {
++*use;
}
HasPtr::~HasPtr() {
if (--*use == 0) {
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr &rhs) {
++*rhs.use;
if(--*use == 0) {
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
#endif
/////////////////////////////////////////////
//ptrOp.h
/////////////////////////////////////////////
#ifndef __SWAP_H__
#define __SWAP_H__
#include "hasPtr.h"
class HasPtr;
class ptrOp {
public:
ptrOp(HasPtr&, HasPtr&);
void swap(HasPtr&, HasPtr&);
private:
HasPtr *hasPtr1;
HasPtr *hasPtr2;
};
#endif
#define __SWAP_H__
#include "hasPtr.h"
class HasPtr;
class ptrOp {
public:
ptrOp(HasPtr&, HasPtr&);
void swap(HasPtr&, HasPtr&);
private:
HasPtr *hasPtr1;
HasPtr *hasPtr2;
};
#endif
/////////////////////////////////////////////
//ptrOp.cpp
/////////////////////////////////////////////
#ifndef __PTROP_CPP__
#define __PTROP_CPP__
#include "ptrOp.h"
ptrOp::ptrOp(HasPtr& hasPtr1, HasPtr& hasPtr2) {
this->hasPtr1 = &hasPtr1;
this->hasPtr2 = &hasPtr2;
}
void ptrOp::swap(HasPtr &lhs, HasPtr &rhs) {
using std::swap;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
swap(hasPtr1->ps, hasPtr2->ps);
swap(hasPtr1->i, hasPtr2->i);
}
#endif
#define __PTROP_CPP__
#include "ptrOp.h"
ptrOp::ptrOp(HasPtr& hasPtr1, HasPtr& hasPtr2) {
this->hasPtr1 = &hasPtr1;
this->hasPtr2 = &hasPtr2;
}
void ptrOp::swap(HasPtr &lhs, HasPtr &rhs) {
using std::swap;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
swap(hasPtr1->ps, hasPtr2->ps);
swap(hasPtr1->i, hasPtr2->i);
}
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include <iostream>
#include "hasPtr.h"
#include "ptrOp.h"
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
HasPtr *hasPtr1 = new HasPtr("string 1");
HasPtr *hasPtr2 = new HasPtr("string 2");
HasPtr *hasPtr3 = new HasPtr("string 3");
HasPtr *hasPtr4 = new HasPtr("string 4");
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
cout << "hasPtr3:" << endl;
hasPtr3->display();
cout << "hasPtr4:" << endl;
hasPtr4->display();
ptrOp *ptrOp1 = new ptrOp(*hasPtr1, *hasPtr2);
ptrOp1->swap(*hasPtr3, *hasPtr4);
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
cout << "hasPtr3:" << endl;
hasPtr3->display();
cout << "hasPtr4:" << endl;
hasPtr4->display();
delete hasPtr1;
delete hasPtr2;
delete hasPtr3;
delete hasPtr4;
return 0;
}
#include "hasPtr.h"
#include "ptrOp.h"
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
HasPtr *hasPtr1 = new HasPtr("string 1");
HasPtr *hasPtr2 = new HasPtr("string 2");
HasPtr *hasPtr3 = new HasPtr("string 3");
HasPtr *hasPtr4 = new HasPtr("string 4");
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
cout << "hasPtr3:" << endl;
hasPtr3->display();
cout << "hasPtr4:" << endl;
hasPtr4->display();
ptrOp *ptrOp1 = new ptrOp(*hasPtr1, *hasPtr2);
ptrOp1->swap(*hasPtr3, *hasPtr4);
cout << "hasPtr1:" << endl;
hasPtr1->display();
cout << "hasPtr2:" << endl;
hasPtr2->display();
cout << "hasPtr3:" << endl;
hasPtr3->display();
cout << "hasPtr4:" << endl;
hasPtr4->display();
delete hasPtr1;
delete hasPtr2;
delete hasPtr3;
delete hasPtr4;
return 0;
}
#############################################
#Makefile
#############################################
.PHONY: clean
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o hasPtr.o ptrOp.o
g++ -o $@ $^
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o hasPtr.o ptrOp.o
g++ -o $@ $^
11) inline
/////////////////////////////////////////////
//rectangle.h
/////////////////////////////////////////////
#ifndef __RECTANGLE_H__
#define __RECTANGLE_H__
#include <iostream>
using std::cout;
using std::endl;
class rectangle {
public:
rectangle(int, int);
virtual ~rectangle();
inline int area() {
return width * height;
}
private:
int width;
int height;
};
#endif
#define __RECTANGLE_H__
#include <iostream>
using std::cout;
using std::endl;
class rectangle {
public:
rectangle(int, int);
virtual ~rectangle();
inline int area() {
return width * height;
}
private:
int width;
int height;
};
#endif
/////////////////////////////////////////////
//rectangle.cpp
/////////////////////////////////////////////
#ifndef __RECTANGLE_CPP__
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle(int width, int height) {
this->width = width;
this->height = height;
}
rectangle::~rectangle() {
}
#endif
#define __RECTANGLE_CPP__
#include "rectangle.h"
rectangle::rectangle(int width, int height) {
this->width = width;
this->height = height;
}
rectangle::~rectangle() {
}
#endif
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include <iostream>
#include "rectangle.h"
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
rectangle *rect = new rectangle(2, 3);
cout << rect->area() << endl;
delete rect;
return 0;
}
#include "rectangle.h"
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
rectangle *rect = new rectangle(2, 3);
cout << rect->area() << endl;
delete rect;
return 0;
}
#############################################
#Makefile
#############################################
.PHONY: clean
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o rectangle.o
g++ -o $@ $^
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o rectangle.o
g++ -o $@ $^
21) vector
/////////////////////////////////////////////
//main.cpp
/////////////////////////////////////////////
#include <vector>
#include <iostream>
#include <string>
using std::vector;
using std::cout;
using std::endl;
using std::string;
int main(int argc, char* argv[]) {
vector<int> a;
if(a.empty()) {
for (int i = 0; i != 3; ++i) {
a.push_back(i+10);
}
}
cout << "a size: " << a.size() << " max size: " << a.max_size() << endl;
vector<int> b(a);
cout << "b size: " << b.size() << " max size: " << b.max_size() << endl;
cout << "b capacity: " << b.capacity() << endl;
b.resize(10);
b.reserve(100);
cout << "b size: " << b.size() << " max size: " << b.max_size() << endl;
cout << "b capacity: " << b.capacity() << endl;
vector<int> c = a;
vector<int> d(3);
cout << d[0] << endl;
while(d != a) {
d = a;
cout << d[0] << endl;
}
vector<int> e(3, 2);
cout << e[0] << endl;
//supported in C++11
vector<int> f{1, 2, 3};
vector<int> g = {4, 5, 6};
vector<int> h{1,2,3};
for (auto &i : h) {
i *= i;
}
for (auto i : h) {
cout << i << " ";
}
cout << endl;
//cout << decltype(h.size()) << endl;
for (auto it = h.cbegin(); it != h.cend(); ++it) {
if(*it == 1) {
//illegal
//*it = 1;
}
cout << *it << " ";
}
cout << endl;
for (auto it = h.crbegin(); it != h.crend(); ++it) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) {
if(*it == 10) {
*it = 0;
}
}
for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::reverse_iterator it = a.rbegin(); it != a.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::const_iterator it = a.begin(); it != a.end(); ++it) {
if(*it == 11) {
//is not legal
//*it = 1;
}
}
for (vector<int>::const_iterator it = a.begin(); it != a.end(); ++it) {
cout << *it << " ";
}
cout << endl;
int i = 0;
for (vector<int>::iterator it = b.begin(); it != b.end(); ++it) {
*it = i;
i++;
}
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.pop_back();
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.insert(b.begin() + 1, 10);
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.erase(b.begin() + 3);
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.swap(c);
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.clear();
cout << "b size: " << b.size() << " max size: " << b.max_size() << endl;
return 0;
}
#include <iostream>
#include <string>
using std::vector;
using std::cout;
using std::endl;
using std::string;
int main(int argc, char* argv[]) {
vector<int> a;
if(a.empty()) {
for (int i = 0; i != 3; ++i) {
a.push_back(i+10);
}
}
cout << "a size: " << a.size() << " max size: " << a.max_size() << endl;
vector<int> b(a);
cout << "b size: " << b.size() << " max size: " << b.max_size() << endl;
cout << "b capacity: " << b.capacity() << endl;
b.resize(10);
b.reserve(100);
cout << "b size: " << b.size() << " max size: " << b.max_size() << endl;
cout << "b capacity: " << b.capacity() << endl;
vector<int> c = a;
vector<int> d(3);
cout << d[0] << endl;
while(d != a) {
d = a;
cout << d[0] << endl;
}
vector<int> e(3, 2);
cout << e[0] << endl;
//supported in C++11
vector<int> f{1, 2, 3};
vector<int> g = {4, 5, 6};
vector<int> h{1,2,3};
for (auto &i : h) {
i *= i;
}
for (auto i : h) {
cout << i << " ";
}
cout << endl;
//cout << decltype(h.size()) << endl;
for (auto it = h.cbegin(); it != h.cend(); ++it) {
if(*it == 1) {
//illegal
//*it = 1;
}
cout << *it << " ";
}
cout << endl;
for (auto it = h.crbegin(); it != h.crend(); ++it) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) {
if(*it == 10) {
*it = 0;
}
}
for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::reverse_iterator it = a.rbegin(); it != a.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::const_iterator it = a.begin(); it != a.end(); ++it) {
if(*it == 11) {
//is not legal
//*it = 1;
}
}
for (vector<int>::const_iterator it = a.begin(); it != a.end(); ++it) {
cout << *it << " ";
}
cout << endl;
int i = 0;
for (vector<int>::iterator it = b.begin(); it != b.end(); ++it) {
*it = i;
i++;
}
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.pop_back();
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.insert(b.begin() + 1, 10);
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.erase(b.begin() + 3);
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.swap(c);
for (auto it = b.cbegin(); it != b.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
b.clear();
cout << "b size: " << b.size() << " max size: " << b.max_size() << endl;
return 0;
}
#############################################
#Makefile
#############################################
.PHONY: clean
CPPFLAGS = -std=c++0x
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o
g++ -o $@ $^
CPPFLAGS = -std=c++0x
all: clean a.out
clean:
rm -rf *.o *.exe *.out
a.out: main.o
g++ -o $@ $^
cpp compile steps
//base.h
#ifndef __BASE_H__
#define __BASE_H__
#include <iostream>
using std::cout;
using std::endl;
class basePoint {
public:
void setPoint(int, int);
void display();
private:
int x;
int y;
};
#endif
//base.cpp
#ifndef __BASE_CPP__
#define __BASE_CPP__
#include "base.h"
void basePoint::setPoint(int x, int y) {
this->x = x;
this->y = y;
}
void basePoint::display() {
std::cout << x << " " << y << std::endl;
}
#endif
//main.cpp
#include "base.h"
int main(int argc, char* argv[]) {
basePoint bp0;
basePoint *bp1 = new basePoint();
bp0.setPoint(1, 2);
bp1->setPoint(3, 4);
bp0.display();
bp1->display();
return 0;
}
compile steps:
$ g++ -c base.cpp -o base.o
$ ar cr libbase.a base.o
$ g++ -c -I. main.cpp
$ g++ -o main main.o -L. -lbase
Saturday, February 22, 2014
VHDL code for serial interface
1) Design requirement:
This lab is to test your understanding of
Serial Port Interface (SPI). Your design
shall accept a 50 megahertz clock signal, an asynchronous active low reset signal,
an asynchronous 1-bit Load signal, an asynchronous 2-bit slave selection signal , an asynchronous 5-bit data signal. Your design shall have a master
SPI controller which will accept the signals describe above and shall
communicate with 3 slaves over a 3 wire SPI bus. Each slave shall drive 5 LEDs
correspond to the 5-bit data received from the master as described in the table
below.
slave selection [1:0]
|
Load
|
Definition
|
01
|
Rising edge
|
The master shall capture the data and send it to
slave #1 and slave # 1 shall drive the LEDs with the data
|
10
|
Rising edge
|
The master shall capture the data and send it to
slave #2 and slave # 2 shall drive the LEDs with the data
|
11
|
Rising edge
|
The master shall capture the data and send it to
slave #3 and slave # 3 shall drive the LEDs with the data
|
SPI
Timing Diagram
2) VHDL code:
library ieee;
use ieee.std_logic_1164.all;
--spi master
entity spi_m is
port (
clk : in std_logic;
rst_n : in std_logic;
load : in std_logic;
slv_sel : in std_logic_vector(1 downto 0);
din : in std_logic_vector(4 downto 0);
sclk : out std_logic;
cs_n : out std_logic_vector(2 downto 0);
sdio : inout std_logic
);
end entity spi_m;
--begin of architecture
architecture behavioral of spi_m is
type spi_status is (IDLE, LOADDATA, SENDDATA, DONE);
signal clk_en : std_logic ;
signal load_ff1 : std_logic ;
signal load_ff2 : std_logic ;
signal load_ff3 : std_logic ;
signal load_trig : std_logic ;
signal slv_sel_ff1 : std_logic_vector(1 downto 0) ;
signal slv_sel_ff2 : std_logic_vector(1 downto 0) ;
signal spi_stat : spi_status ;
signal spi_stat_nxt : spi_status ;
signal data : std_logic_vector(4 downto 0) ;
signal index : integer range 0 to 10 ;
signal sdi : std_logic ;
signal sdo_en : std_logic ;
begin
--generate sclk
sclk <= clk when clk_en = '1' else '0';
--generate sdio
sdio <= data(4) when sdo_en = '1' else 'Z';
--get sdi
sdi <= sdio;
--solve the metastability of async input
process(clk, rst_n)
begin
if(rst_n = '0') then
load_ff1 <= '0';
load_ff2 <= '0';
load_ff3 <= '0';
slv_sel_ff1 <= "00";
slv_sel_ff2 <= "00";
elsif(rising_edge(clk)) then
load_ff1 <= load;
load_ff2 <= load_ff1;
load_ff3 <= load_ff2;
slv_sel_ff1 <= slv_sel;
slv_sel_ff2 <= slv_sel_ff1;
end if;
end process;
--get the change of load
load_trig <= load_ff2 and (not load_ff3);
--generate cs_n
process(clk, rst_n)
begin
if(rst_n = '0') then
cs_n <= "111";
elsif(rising_edge(clk)) then
if(spi_stat = IDLE) then
case slv_sel_ff2 is
when "01" =>
cs_n <= "110";
when "10" =>
cs_n <= "101";
when "11" =>
cs_n <= "011";
when others =>
cs_n <= "111";
end case;
end if;
end if;
end process;
--generate clk_en
process(clk, rst_n)
begin
if(rst_n = '0') then
clk_en <= '0';
elsif(falling_edge(clk)) then
if((spi_stat = SENDDATA) or (spi_stat = DONE)) then
clk_en <= '1';
else
clk_en <= '0';
end if;
end if;
end process;
--generate data
process(clk, rst_n)
begin
if(rst_n = '0') then
data <= (others => '0');
elsif(rising_edge(clk)) then
if(spi_stat = LOADDATA) then
data <= din;
elsif(spi_stat = SENDDATA) then
data <= data(3 downto 0) & '0';
end if;
end if;
end process;
--count index
process(clk, rst_n)
begin
if(rst_n = '0') then
index <= 0;
elsif(rising_edge(clk)) then
if(spi_stat = SENDDATA) then
index <= index + 1;
else
index <= 0;
end if;
end if;
end process;
--generate sdo_en
process(clk, rst_n)
begin
if(rst_n = '0') then
sdo_en <= '0';
elsif(rising_edge(clk)) then
if((spi_stat = LOADDATA) or (spi_stat = SENDDATA)) then
sdo_en <= '1';
else
sdo_en <= '0';
end if;
end if;
end process;
--spi master state machine
process(spi_stat, load_trig, index)
begin
case spi_stat is
when IDLE =>
if(load_trig = '1') then
spi_stat_nxt <= LOADDATA;
else
spi_stat_nxt <= IDLE;
end if;
when LOADDATA =>
spi_stat_nxt <= SENDDATA;
when SENDDATA =>
if(index <= 2) then
spi_stat_nxt <= SENDDATA;
else
spi_stat_nxt <= DONE;
end if;
when DONE =>
spi_stat_nxt <= IDLE;
when others =>
spi_stat_nxt <= IDLE;
end case;
end process;
--flip-flop spi_stat
process(clk, rst_n)
begin
if(rst_n = '0') then
spi_stat <= IDLE;
elsif(rising_edge(clk)) then
spi_stat <= spi_stat_nxt;
end if;
end process;
--end of architecture
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
--spi slave
entity spi_s is
port (
sclk : in std_logic;
rst_n : in std_logic;
cs_n : in std_logic;
sdio : inout std_logic;
led : out std_logic_vector(4 downto 0)
);
end entity spi_s;
--begin of architecture
architecture behavioral of spi_s is
signal sdi : std_logic;
signal sdo : std_logic;
signal sdo_en : std_logic;
signal data : std_logic_vector(4 downto 0);
begin
sdi <= sdio;
sdio <= sdo when sdo_en = '1' else 'Z';
sdo_en <= '0';
sdo <= '0';
process(sclk, rst_n)
begin
if(rst_n = '0') then
data <= "00000";
elsif(rising_edge(sclk)) then
if(cs_n = '0') then
data <= data(3 downto 0) & sdi;
end if;
end if;
end process;
led <= data;
--end of architecture
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
entity top is
port (
clk : in std_logic;
rst_n : in std_logic;
load : in std_logic;
slv_sel : in std_logic_vector(1 downto 0);
din : in std_logic_vector(4 downto 0);
led0 : out std_logic_vector(4 downto 0);
led1 : out std_logic_vector(4 downto 0);
led2 : out std_logic_vector(4 downto 0)
);
end entity top;
architecture behavioral of top is
component spi_m is
port (
clk : in std_logic;
rst_n : in std_logic;
load : in std_logic;
slv_sel : in std_logic_vector(1 downto 0);
din : in std_logic_vector(4 downto 0);
sclk : out std_logic;
cs_n : out std_logic_vector(2 downto 0);
sdio : inout std_logic
);
end component;
component spi_s is
port (
sclk : in std_logic;
rst_n : in std_logic;
cs_n : in std_logic;
sdio : inout std_logic;
led : out std_logic_vector(4 downto 0)
);
end component;
signal sclk: std_logic;
signal cs_n: std_logic_vector(2 downto 0);
signal sdio: std_logic;
begin
u_spi_m: spi_m port map (
clk => clk ,
rst_n => rst_n ,
load => load ,
slv_sel => slv_sel ,
din => din ,
sclk => sclk ,
cs_n => cs_n ,
sdio => sdio
);
u_spi0: spi_s port map (
sclk => sclk,
rst_n => rst_n,
cs_n => cs_n(0),
sdio => sdio,
led => led0
);
u_spi1: spi_s port map (
sclk => sclk,
rst_n => rst_n,
cs_n => cs_n(1),
sdio => sdio,
led => led1
);
u_spi2: spi_s port map (
sclk => sclk,
rst_n => rst_n,
cs_n => cs_n(2),
sdio => sdio,
led => led2
);
end behavioral;
Friday, February 14, 2014
use VHDL to write a counter with more functions(2)
--Selector[1:0] | Boundary enable | Output [N: 0]
----------------------------------------------------------------
--00 0 or 1 0
--01 0 Increment count by 7 from Boundary to 255 every half second and stop
--10 0 Decrement count by 9 from 255 to Boundary every half second and stop
--11 0 Increment count by 11 from Boundary to 255 then decrement by 15 to Boundary every half second and stop
--01 1 Increment count by 8 from 1 to Boundary every half second and stop
--10 1 Decrement count by 13 from Boundary to 0 every half second and stop
--11 1 Increment count by 14 from 1 to Boundary then decrement by 6 to 0 every half second and stop
-----------------------------------------------------------------
--clk dividor
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity clk_div is
generic (
N: integer := 12499999
);
port (
clk : in std_logic;
rst_n : in std_logic;
clk_out : out std_logic
);
end entity clk_div;
architecture behavioral of clk_div is
signal clk_cnt : integer range 0 to N;
signal clk_out_tmp : std_logic;
begin
--counter for half second
process(clk, rst_n)
begin
if(rst_n = '0')then
clk_cnt <= 0;
clk_out_tmp <= '0';
elsif(clk'event and clk = '1') then
--when counter reaches to half second,
--need to reset the counter to 0
if(clk_cnt = N) then
clk_cnt <= 0;
clk_out_tmp <= not (clk_out_tmp);
else
clk_cnt <= clk_cnt + 1;
clk_out_tmp <= clk_out_tmp;
end if;
end if;
end process;
clk_out <= clk_out_tmp;
end behavioral;
-----------------------------------------------------------------
--kernel counter
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity kernel_counter is
generic (
CNT_LEN : integer := 8
);
port (
clk_in : in std_logic;
rst_n : in std_logic;
cnt_restart : in std_logic;
cnt_type : in std_logic;
cnt_inc : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_st_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_end_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_out : out std_logic_vector(CNT_LEN-1 downto 0);
cnt_done : out std_logic
);
end entity kernel_counter;
architecture behavioral of kernel_counter is
signal cnt_end_data_new : std_logic_vector(CNT_LEN-1 downto 0);
signal cnt : std_logic_vector(CNT_LEN-1 downto 0);
signal cnt_end : std_logic_vector(CNT_LEN-1 downto 0);
type cnt_status is (IDLE, LOAD, INC, DEC, DONE);
signal cnt_stat : cnt_status;
signal cnt_stat_nxt : cnt_status;
--signal cnt_type_ff1 : std_logic;
begin
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_end_data_new <= x"00";
elsif(rising_edge(clk_in)) then
if(cnt_stat = LOAD) then
cnt_end_data_new <= cnt_end_data;
end if;
end if;
end process;
--when counter increase or decrease, get the last data that the counter can reach when counting
--process(cnt_restart, cnt_type_ff1, cnt_end_data, cnt_inc)
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_end <= x"00";
elsif(rising_edge(clk_in)) then
if(cnt_stat = LOAD) then
if(cnt_type = '0') then
cnt_end <= cnt_end_data - cnt_inc - cnt_inc;
else
cnt_end <= cnt_end_data + cnt_inc + cnt_inc;
end if;
end if;
end if;
end process;
--counter state machine
--counter to count how many half seconds
process(cnt_stat, cnt_type, cnt, cnt_end, cnt_restart)
begin
case cnt_stat is
when IDLE =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
else
cnt_stat_nxt <= IDLE;
end if;
when LOAD =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
elsif(cnt_type = '0') then
cnt_stat_nxt <= INC;
else
cnt_stat_nxt <= DEC;
end if;
when INC =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
elsif(cnt >= cnt_end) then
cnt_stat_nxt <= DONE;
else
cnt_stat_nxt <= INC;
end if;
when DEC =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
elsif(cnt <= cnt_end) then
cnt_stat_nxt <= DONE;
else
cnt_stat_nxt <= DEC;
end if;
when DONE =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
else
cnt_stat_nxt <= IDLE;
end if;
when others =>
cnt_stat_nxt <= cnt_stat;
end case;
end process;
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_stat <= IDLE;
elsif(rising_edge(clk_in)) then
cnt_stat <= cnt_stat_nxt;
end if;
end process;
--cnt done
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_done <= '0';
elsif(rising_edge(clk_in)) then
if(cnt_stat = DONE) then
cnt_done <= '1';
else
cnt_done <= '0';
end if;
end if;
end process;
--one half second count
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt <= (others => '0');
elsif(rising_edge(clk_in)) then
if(cnt_stat = LOAD) then
cnt <= cnt_st_data;
elsif(cnt_stat = INC) then
cnt <= cnt + cnt_inc;
elsif(cnt_stat = DEC) then
cnt <= cnt - cnt_inc;
elsif(cnt_stat = DONE) then
cnt <= cnt_end_data_new;
end if;
end if;
end process;
--send data out
cnt_out <= cnt;
end behavioral;
-----------------------------------------------------------------
--counter
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity counter is
port (
clk_in : in std_logic;
rst_n : in std_logic;
selector : in std_logic_vector(1 downto 0);
boundary_en : in std_logic;
boundary_data : in std_logic_vector(7 downto 0);
data : out std_logic_vector(7 downto 0)
);
end entity counter;
architecture behavioral of counter is
--signal declaration in architecture
signal selector_ff1 : std_logic_vector(1 downto 0);
signal selector_ff2 : std_logic_vector(1 downto 0);
signal selector_ff3 : std_logic_vector(1 downto 0);
signal selector_trig : std_logic_vector(3 downto 0);
signal selector_trig_for_rvs : std_logic_vector(3 downto 0);
signal boundary_en_ff1 : std_logic;
signal boundary_en_ff2 : std_logic;
signal boundary_en_ff3 : std_logic;
signal boundary_en_trig : std_logic;
signal boundary_data_ff1 : std_logic_vector(7 downto 0);
signal boundary_data_ff2 : std_logic_vector(7 downto 0);
signal boundary_data_ff3 : std_logic_vector(7 downto 0);
signal boundary_data_trig : std_logic;
signal cnt_restart : std_logic;
signal reverse : std_logic;
signal reverse_ff1 : std_logic;
signal reverse_trig : std_logic;
signal reverse_nxt : std_logic;
signal cnt_type : std_logic;
signal cnt_inc : std_logic_vector(7 downto 0);
signal cnt_st_data : std_logic_vector(7 downto 0);
signal cnt_end_data : std_logic_vector(7 downto 0);
signal cnt_out : std_logic_vector(7 downto 0);
signal cnt_inc_end : std_logic_vector(7 downto 0);
signal cnt_en_trig : std_logic;
signal cnt_dis_trig : std_logic;
signal cnt_type_1_trig : std_logic;
signal cnt_done : std_logic;
constant select01_boundary0_inc : std_logic_vector(7 downto 0) := x"07" ;
constant select01_boundary1_inc : std_logic_vector(7 downto 0) := x"08" ;
constant select10_boundary0_dec : std_logic_vector(7 downto 0) := x"09" ;
constant select10_boundary1_dec : std_logic_vector(7 downto 0) := x"0d" ;
constant select11_boundary0_inc : std_logic_vector(7 downto 0) := x"0b" ;
constant select11_boundary1_inc : std_logic_vector(7 downto 0) := x"0e" ;
constant select11_boundary0_dec : std_logic_vector(7 downto 0) := x"0f" ;
constant select11_boundary1_dec : std_logic_vector(7 downto 0) := x"06" ;
--function to convert boolean to std_logic
function to_stdulogic(V: Boolean) return std_ulogic is
begin
if V then
return '1';
else
return '0';
end if;
end to_stdulogic;
--kernel counter
component kernel_counter is
generic (
CNT_LEN : integer := 8
);
port (
clk_in : in std_logic;
rst_n : in std_logic;
cnt_restart : in std_logic;
cnt_type : in std_logic;
cnt_inc : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_st_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_end_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_out : out std_logic_vector(CNT_LEN-1 downto 0);
cnt_done : out std_logic
);
end component;
--begin of architecture
begin
--instance kernel counter
u_kernel_counter: kernel_counter generic map (
CNT_LEN => 8
) port map (
clk_in => clk_in ,
rst_n => rst_n ,
cnt_restart => cnt_restart ,
cnt_type => cnt_type ,
cnt_inc => cnt_inc ,
cnt_st_data => cnt_st_data ,
cnt_end_data => cnt_end_data ,
cnt_out => cnt_out ,
cnt_done => cnt_done
);
--solve metastability issue, so 2 flip-flops are needed
--sample the change of selector, so 3 flip-flops are needed
--so add 3 flip-flops
process(clk_in, rst_n)
begin
if(rst_n = '0') then
selector_ff1 <= b"00" ;
selector_ff2 <= b"00" ;
selector_ff3 <= b"00" ;
boundary_en_ff1 <= '0' ;
boundary_en_ff2 <= '0' ;
boundary_en_ff3 <= '0' ;
boundary_data_ff1 <= x"00" ;
boundary_data_ff2 <= x"00" ;
boundary_data_ff3 <= x"00" ;
elsif(clk_in'event and clk_in = '1') then
selector_ff1 <= selector ;
selector_ff2 <= selector_ff1 ;
selector_ff3 <= selector_ff2 ;
boundary_en_ff1 <= boundary_en ;
boundary_en_ff2 <= boundary_en_ff1 ;
boundary_en_ff3 <= boundary_en_ff2 ;
boundary_data_ff1 <= boundary_data ;
boundary_data_ff2 <= boundary_data_ff1 ;
boundary_data_ff3 <= boundary_data_ff2 ;
end if;
end process;
boundary_data_trig <= to_stdulogic(boundary_data_ff2 /= boundary_data_ff3);
boundary_en_trig <= to_stdulogic(boundary_en_ff2 /= boundary_en_ff3);
--sample the change of selector
--use each bit to represent one selector
selector_trig_for_rvs(0) <= to_stdulogic(
((selector_ff2 = b"00") and (selector_ff3 /= b"00")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"00"))
);
selector_trig_for_rvs(1) <= to_stdulogic(
((selector_ff2 = b"01") and (selector_ff3 /= b"01")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"01"))
);
selector_trig_for_rvs(2) <= to_stdulogic(
((selector_ff2 = b"10") and (selector_ff3 /= b"10")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"10"))
);
selector_trig_for_rvs(3) <= to_stdulogic(
((selector_ff2 = b"11") and (selector_ff3 /= b"11")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"11"))
);
selector_trig <= to_stdulogic(
((selector_ff2 = b"11") and (selector_ff3 /= b"11")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1') or (reverse_trig = '1')) and (selector_ff2 = b"11"))
) & selector_trig_for_rvs(2) & selector_trig_for_rvs(1) & selector_trig_for_rvs(0);
--when selector is change, calculate the next data displayed on screen
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_st_data <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"0001" =>
cnt_st_data <= x"00";
when b"0010" =>
if(boundary_en_ff2 = '0') then
cnt_st_data <= boundary_data_ff2;
else
cnt_st_data <= x"01";
end if;
when b"0100" =>
if(boundary_en_ff2 = '0') then
cnt_st_data <= x"ff";
else
cnt_st_data <= boundary_data_ff2;
end if;
when b"1000" =>
if(boundary_en_ff2 = '0') then
if(reverse = '1') then
cnt_st_data <= x"ff" - select11_boundary0_dec;
else
cnt_st_data <= boundary_data_ff2;
end if;
else
if(reverse = '1') then
cnt_st_data <= boundary_data_ff2 - select11_boundary1_dec;
else
cnt_st_data <= x"01";
end if;
end if;
when others =>
cnt_st_data <= cnt_st_data;
end case;
end if;
end process;
--when counter cannot counter but has not reached the last data, calculate the last data to display
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_end_data <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"0001" =>
cnt_end_data <= x"00";
when b"0010" =>
if(boundary_en_ff2 = '0') then
cnt_end_data <= x"ff";
else
cnt_end_data <= boundary_data_ff2;
end if;
when b"0100" =>
if(boundary_en_ff2 = '0') then
cnt_end_data <= boundary_data_ff2;
else
cnt_end_data <= x"00";
end if;
when b"1000" =>
if(boundary_en_ff2 = '0') then
if(reverse = '1') then
cnt_end_data <= boundary_data_ff2;
else
cnt_end_data <= x"ff";
end if;
else
if(reverse = '1') then
cnt_end_data <= x"00";
else
cnt_end_data <= boundary_data_ff2;
end if;
end if;
when others =>
cnt_end_data <= cnt_end_data;
end case;
end if;
end process;
--counter increment or decrement for each clock
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_inc <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"0001" =>
cnt_inc <= x"00";
when b"0010" =>
if(boundary_en_ff2 = '0') then
cnt_inc <= select01_boundary0_inc;
else
cnt_inc <= select01_boundary1_inc;
end if;
when b"0100" =>
if(boundary_en_ff2 = '0') then
cnt_inc <= select10_boundary0_dec;
else
cnt_inc <= select10_boundary1_dec;
end if;
when b"1000" =>
if(boundary_en_ff2 = '0') then
if(reverse = '1') then
cnt_inc <= select11_boundary0_dec;
else
cnt_inc <= select11_boundary0_inc;
end if;
else
if(reverse = '1') then
cnt_inc <= select11_boundary1_dec;
else
cnt_inc <= select11_boundary1_inc;
end if;
end if;
when others =>
cnt_inc <= cnt_inc;
end case;
end if;
end process;
--when counter increase in mode 3, get the last data that the counter can reach when counting
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_inc_end <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"1000" =>
if(boundary_en_ff2 = '0') then
cnt_inc_end <= x"ff" - select11_boundary0_inc;
else
cnt_inc_end <= boundary_data_ff2 - select11_boundary1_inc;
end if;
when others =>
cnt_inc_end <= cnt_inc_end;
end case;
end if;
end process;
--signal to control whether it is an increment or decrement
cnt_type_1_trig <= to_stdulogic((selector_ff2 = "11" and (reverse_trig = '1' or reverse = '1')) or (selector_ff2 = "10"));
--process(cnt_type_1_trig)
--begin
-- if(cnt_type_1_trig = '1') then
-- cnt_type <= '1';
-- else
-- cnt_type <= '0';
-- end if;
--end process;
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_type <= '0';
elsif(clk_in'event and clk_in = '1') then
if(cnt_type_1_trig = '1') then
cnt_type <= '1';
else
cnt_type <= '0';
end if;
end if;
end process;
--when in mode3, reverse will be changed to 1 when counter reach to the last data when increasing
process(clk_in, rst_n)
begin
if(rst_n = '0') then
reverse <= '0';
elsif(clk_in'event and clk_in = '1') then
if(selector_trig_for_rvs /= x"0") then
reverse <= '0';
elsif(selector_ff2 = b"11") then
if(reverse = '0') then
if(cnt_out >= cnt_inc_end) then
reverse <= '1';
else
reverse <= reverse;
end if;
else
reverse <= reverse;
end if;
else
reverse <= '0';
end if;
end if;
end process;
--delay reverse one cycle
process(clk_in, rst_n)
begin
if(rst_n = '0') then
reverse_ff1 <= '0';
elsif(clk_in'event and clk_in = '1') then
reverse_ff1 <= reverse;
end if;
end process;
--find a reverse change in mode3
reverse_trig <= reverse and (not reverse_ff1);
--signal to trigger kernel counter to restart
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_restart <= '0';
elsif(clk_in'event and clk_in = '1') then
cnt_restart <= selector_trig(0) or selector_trig(1) or selector_trig(2) or selector_trig(3);
end if;
end process;
--send the counter data out
data <= cnt_out;
end behavioral;
--end of architecture
-----------------------------------------------------------------
--convert to segment
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity hex2segment is
generic (
M: integer := 7
);
port (
hex : in std_logic_vector(3 downto 0);
segment : out std_logic_vector(M-1 downto 0)
);
end entity hex2segment;
architecture behavioral of hex2segment is
begin
SEGMENT_WITHOUT_DP: if M=7 generate
process(hex)
begin
case hex is
--decode from hex to segment
when x"0" => segment <= b"1000000";
when x"1" => segment <= b"1111001";
when x"2" => segment <= b"0100100";
when x"3" => segment <= b"0110000";
when x"4" => segment <= b"0011001";
when x"5" => segment <= b"0010010";
when x"6" => segment <= b"0000010";
when x"7" => segment <= b"1111000";
when x"8" => segment <= b"0000000";
when x"9" => segment <= b"0010000";
when x"a" => segment <= b"0001000";
when x"b" => segment <= b"0000011";
when x"c" => segment <= b"1000110";
when x"d" => segment <= b"0100001";
when x"e" => segment <= b"0000110";
when x"f" => segment <= b"0001110";
--when in selector 1, counter should add 1 after each half second
--for other unknown selectors, set counter to 0
when others => segment <= b"1000000";
end case;
end process;
end generate SEGMENT_WITHOUT_DP;
SEGMENT_WITH_DP: if M=8 generate
process(hex)
begin
case hex is
--decode from hex to segment
when x"0" => segment <= b"11000000";
when x"1" => segment <= b"11111001";
when x"2" => segment <= b"10100100";
when x"3" => segment <= b"10110000";
when x"4" => segment <= b"10011001";
when x"5" => segment <= b"10010010";
when x"6" => segment <= b"10000010";
when x"7" => segment <= b"11111000";
when x"8" => segment <= b"10000000";
when x"9" => segment <= b"10010000";
when x"a" => segment <= b"10001000";
when x"b" => segment <= b"10000011";
when x"c" => segment <= b"11000110";
when x"d" => segment <= b"10100001";
when x"e" => segment <= b"10000110";
when x"f" => segment <= b"10001110";
--when in selector 1, counter should add 1 after each half second
--for other unknown selectors, set counter to 0
when others => segment <= b"11000000";
end case;
end process;
end generate SEGMENT_WITH_DP;
end behavioral;
-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity top is
generic (
M: integer := 7;
N: integer := 12499999
);
port (
clk : in std_logic;
rst_n : in std_logic;
selector : in std_logic_vector(1 downto 0);
boundary_en : in std_logic;
boundary_data : in std_logic_vector(7 downto 0);
data : out std_logic_vector(7 downto 0);
segment0 : out std_logic_vector(M-1 downto 0);
segment1 : out std_logic_vector(M-1 downto 0)
);
end entity top;
architecture behavioral of top is
--signal declaration in architecture
signal clk_out : std_logic;
signal data_tmp : std_logic_vector(7 downto 0);
signal hex : std_logic_vector(11 downto 0);
component clk_div is
generic (
N: integer := 12499999
);
port (
clk : in std_logic;
rst_n : in std_logic;
clk_out : out std_logic
);
end component;
component counter is
port (
clk_in : in std_logic;
rst_n : in std_logic;
selector : in std_logic_vector(1 downto 0);
boundary_en : in std_logic;
boundary_data : in std_logic_vector(7 downto 0);
data : out std_logic_vector(7 downto 0)
);
end component;
component hex2segment is
generic (
M: integer := 7
);
port (
hex : in std_logic_vector(3 downto 0);
segment : out std_logic_vector(M-1 downto 0)
);
end component;
--begin of architecture
begin
--instance clock dividor
u_clk_div: clk_div generic map (
N => N
) PORT MAP (
clk => clk ,
rst_n => rst_n ,
clk_out => clk_out
);
--instance counter
u_counter: counter PORT MAP (
clk_in => clk_out ,
rst_n => rst_n ,
selector => selector ,
boundary_en => boundary_en ,
boundary_data => boundary_data ,
data => data_tmp
);
data <= data_tmp;
--instance segment0
u_hex2segment_0: hex2segment generic map (
M => M
) PORT MAP (
hex => data_tmp(3 downto 0),
segment => segment0
);
--instance segment1
u_hex2segment_1: hex2segment generic map (
M => M
) PORT MAP (
hex => data_tmp(7 downto 4),
segment => segment1
);
end behavioral;
--end of architecture
----------------------------------------------------------------
--00 0 or 1 0
--01 0 Increment count by 7 from Boundary to 255 every half second and stop
--10 0 Decrement count by 9 from 255 to Boundary every half second and stop
--11 0 Increment count by 11 from Boundary to 255 then decrement by 15 to Boundary every half second and stop
--01 1 Increment count by 8 from 1 to Boundary every half second and stop
--10 1 Decrement count by 13 from Boundary to 0 every half second and stop
--11 1 Increment count by 14 from 1 to Boundary then decrement by 6 to 0 every half second and stop
-----------------------------------------------------------------
--clk dividor
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity clk_div is
generic (
N: integer := 12499999
);
port (
clk : in std_logic;
rst_n : in std_logic;
clk_out : out std_logic
);
end entity clk_div;
architecture behavioral of clk_div is
signal clk_cnt : integer range 0 to N;
signal clk_out_tmp : std_logic;
begin
--counter for half second
process(clk, rst_n)
begin
if(rst_n = '0')then
clk_cnt <= 0;
clk_out_tmp <= '0';
elsif(clk'event and clk = '1') then
--when counter reaches to half second,
--need to reset the counter to 0
if(clk_cnt = N) then
clk_cnt <= 0;
clk_out_tmp <= not (clk_out_tmp);
else
clk_cnt <= clk_cnt + 1;
clk_out_tmp <= clk_out_tmp;
end if;
end if;
end process;
clk_out <= clk_out_tmp;
end behavioral;
-----------------------------------------------------------------
--kernel counter
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity kernel_counter is
generic (
CNT_LEN : integer := 8
);
port (
clk_in : in std_logic;
rst_n : in std_logic;
cnt_restart : in std_logic;
cnt_type : in std_logic;
cnt_inc : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_st_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_end_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_out : out std_logic_vector(CNT_LEN-1 downto 0);
cnt_done : out std_logic
);
end entity kernel_counter;
architecture behavioral of kernel_counter is
signal cnt_end_data_new : std_logic_vector(CNT_LEN-1 downto 0);
signal cnt : std_logic_vector(CNT_LEN-1 downto 0);
signal cnt_end : std_logic_vector(CNT_LEN-1 downto 0);
type cnt_status is (IDLE, LOAD, INC, DEC, DONE);
signal cnt_stat : cnt_status;
signal cnt_stat_nxt : cnt_status;
--signal cnt_type_ff1 : std_logic;
begin
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_end_data_new <= x"00";
elsif(rising_edge(clk_in)) then
if(cnt_stat = LOAD) then
cnt_end_data_new <= cnt_end_data;
end if;
end if;
end process;
--when counter increase or decrease, get the last data that the counter can reach when counting
--process(cnt_restart, cnt_type_ff1, cnt_end_data, cnt_inc)
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_end <= x"00";
elsif(rising_edge(clk_in)) then
if(cnt_stat = LOAD) then
if(cnt_type = '0') then
cnt_end <= cnt_end_data - cnt_inc - cnt_inc;
else
cnt_end <= cnt_end_data + cnt_inc + cnt_inc;
end if;
end if;
end if;
end process;
--counter state machine
--counter to count how many half seconds
process(cnt_stat, cnt_type, cnt, cnt_end, cnt_restart)
begin
case cnt_stat is
when IDLE =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
else
cnt_stat_nxt <= IDLE;
end if;
when LOAD =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
elsif(cnt_type = '0') then
cnt_stat_nxt <= INC;
else
cnt_stat_nxt <= DEC;
end if;
when INC =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
elsif(cnt >= cnt_end) then
cnt_stat_nxt <= DONE;
else
cnt_stat_nxt <= INC;
end if;
when DEC =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
elsif(cnt <= cnt_end) then
cnt_stat_nxt <= DONE;
else
cnt_stat_nxt <= DEC;
end if;
when DONE =>
if(cnt_restart = '1') then
cnt_stat_nxt <= LOAD;
else
cnt_stat_nxt <= IDLE;
end if;
when others =>
cnt_stat_nxt <= cnt_stat;
end case;
end process;
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_stat <= IDLE;
elsif(rising_edge(clk_in)) then
cnt_stat <= cnt_stat_nxt;
end if;
end process;
--cnt done
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_done <= '0';
elsif(rising_edge(clk_in)) then
if(cnt_stat = DONE) then
cnt_done <= '1';
else
cnt_done <= '0';
end if;
end if;
end process;
--one half second count
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt <= (others => '0');
elsif(rising_edge(clk_in)) then
if(cnt_stat = LOAD) then
cnt <= cnt_st_data;
elsif(cnt_stat = INC) then
cnt <= cnt + cnt_inc;
elsif(cnt_stat = DEC) then
cnt <= cnt - cnt_inc;
elsif(cnt_stat = DONE) then
cnt <= cnt_end_data_new;
end if;
end if;
end process;
--send data out
cnt_out <= cnt;
end behavioral;
-----------------------------------------------------------------
--counter
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity counter is
port (
clk_in : in std_logic;
rst_n : in std_logic;
selector : in std_logic_vector(1 downto 0);
boundary_en : in std_logic;
boundary_data : in std_logic_vector(7 downto 0);
data : out std_logic_vector(7 downto 0)
);
end entity counter;
architecture behavioral of counter is
--signal declaration in architecture
signal selector_ff1 : std_logic_vector(1 downto 0);
signal selector_ff2 : std_logic_vector(1 downto 0);
signal selector_ff3 : std_logic_vector(1 downto 0);
signal selector_trig : std_logic_vector(3 downto 0);
signal selector_trig_for_rvs : std_logic_vector(3 downto 0);
signal boundary_en_ff1 : std_logic;
signal boundary_en_ff2 : std_logic;
signal boundary_en_ff3 : std_logic;
signal boundary_en_trig : std_logic;
signal boundary_data_ff1 : std_logic_vector(7 downto 0);
signal boundary_data_ff2 : std_logic_vector(7 downto 0);
signal boundary_data_ff3 : std_logic_vector(7 downto 0);
signal boundary_data_trig : std_logic;
signal cnt_restart : std_logic;
signal reverse : std_logic;
signal reverse_ff1 : std_logic;
signal reverse_trig : std_logic;
signal reverse_nxt : std_logic;
signal cnt_type : std_logic;
signal cnt_inc : std_logic_vector(7 downto 0);
signal cnt_st_data : std_logic_vector(7 downto 0);
signal cnt_end_data : std_logic_vector(7 downto 0);
signal cnt_out : std_logic_vector(7 downto 0);
signal cnt_inc_end : std_logic_vector(7 downto 0);
signal cnt_en_trig : std_logic;
signal cnt_dis_trig : std_logic;
signal cnt_type_1_trig : std_logic;
signal cnt_done : std_logic;
constant select01_boundary0_inc : std_logic_vector(7 downto 0) := x"07" ;
constant select01_boundary1_inc : std_logic_vector(7 downto 0) := x"08" ;
constant select10_boundary0_dec : std_logic_vector(7 downto 0) := x"09" ;
constant select10_boundary1_dec : std_logic_vector(7 downto 0) := x"0d" ;
constant select11_boundary0_inc : std_logic_vector(7 downto 0) := x"0b" ;
constant select11_boundary1_inc : std_logic_vector(7 downto 0) := x"0e" ;
constant select11_boundary0_dec : std_logic_vector(7 downto 0) := x"0f" ;
constant select11_boundary1_dec : std_logic_vector(7 downto 0) := x"06" ;
--function to convert boolean to std_logic
function to_stdulogic(V: Boolean) return std_ulogic is
begin
if V then
return '1';
else
return '0';
end if;
end to_stdulogic;
--kernel counter
component kernel_counter is
generic (
CNT_LEN : integer := 8
);
port (
clk_in : in std_logic;
rst_n : in std_logic;
cnt_restart : in std_logic;
cnt_type : in std_logic;
cnt_inc : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_st_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_end_data : in std_logic_vector(CNT_LEN-1 downto 0);
cnt_out : out std_logic_vector(CNT_LEN-1 downto 0);
cnt_done : out std_logic
);
end component;
--begin of architecture
begin
--instance kernel counter
u_kernel_counter: kernel_counter generic map (
CNT_LEN => 8
) port map (
clk_in => clk_in ,
rst_n => rst_n ,
cnt_restart => cnt_restart ,
cnt_type => cnt_type ,
cnt_inc => cnt_inc ,
cnt_st_data => cnt_st_data ,
cnt_end_data => cnt_end_data ,
cnt_out => cnt_out ,
cnt_done => cnt_done
);
--solve metastability issue, so 2 flip-flops are needed
--sample the change of selector, so 3 flip-flops are needed
--so add 3 flip-flops
process(clk_in, rst_n)
begin
if(rst_n = '0') then
selector_ff1 <= b"00" ;
selector_ff2 <= b"00" ;
selector_ff3 <= b"00" ;
boundary_en_ff1 <= '0' ;
boundary_en_ff2 <= '0' ;
boundary_en_ff3 <= '0' ;
boundary_data_ff1 <= x"00" ;
boundary_data_ff2 <= x"00" ;
boundary_data_ff3 <= x"00" ;
elsif(clk_in'event and clk_in = '1') then
selector_ff1 <= selector ;
selector_ff2 <= selector_ff1 ;
selector_ff3 <= selector_ff2 ;
boundary_en_ff1 <= boundary_en ;
boundary_en_ff2 <= boundary_en_ff1 ;
boundary_en_ff3 <= boundary_en_ff2 ;
boundary_data_ff1 <= boundary_data ;
boundary_data_ff2 <= boundary_data_ff1 ;
boundary_data_ff3 <= boundary_data_ff2 ;
end if;
end process;
boundary_data_trig <= to_stdulogic(boundary_data_ff2 /= boundary_data_ff3);
boundary_en_trig <= to_stdulogic(boundary_en_ff2 /= boundary_en_ff3);
--sample the change of selector
--use each bit to represent one selector
selector_trig_for_rvs(0) <= to_stdulogic(
((selector_ff2 = b"00") and (selector_ff3 /= b"00")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"00"))
);
selector_trig_for_rvs(1) <= to_stdulogic(
((selector_ff2 = b"01") and (selector_ff3 /= b"01")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"01"))
);
selector_trig_for_rvs(2) <= to_stdulogic(
((selector_ff2 = b"10") and (selector_ff3 /= b"10")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"10"))
);
selector_trig_for_rvs(3) <= to_stdulogic(
((selector_ff2 = b"11") and (selector_ff3 /= b"11")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1')) and (selector_ff2 = b"11"))
);
selector_trig <= to_stdulogic(
((selector_ff2 = b"11") and (selector_ff3 /= b"11")) or
(((boundary_data_trig = '1') or (boundary_en_trig = '1') or (reverse_trig = '1')) and (selector_ff2 = b"11"))
) & selector_trig_for_rvs(2) & selector_trig_for_rvs(1) & selector_trig_for_rvs(0);
--when selector is change, calculate the next data displayed on screen
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_st_data <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"0001" =>
cnt_st_data <= x"00";
when b"0010" =>
if(boundary_en_ff2 = '0') then
cnt_st_data <= boundary_data_ff2;
else
cnt_st_data <= x"01";
end if;
when b"0100" =>
if(boundary_en_ff2 = '0') then
cnt_st_data <= x"ff";
else
cnt_st_data <= boundary_data_ff2;
end if;
when b"1000" =>
if(boundary_en_ff2 = '0') then
if(reverse = '1') then
cnt_st_data <= x"ff" - select11_boundary0_dec;
else
cnt_st_data <= boundary_data_ff2;
end if;
else
if(reverse = '1') then
cnt_st_data <= boundary_data_ff2 - select11_boundary1_dec;
else
cnt_st_data <= x"01";
end if;
end if;
when others =>
cnt_st_data <= cnt_st_data;
end case;
end if;
end process;
--when counter cannot counter but has not reached the last data, calculate the last data to display
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_end_data <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"0001" =>
cnt_end_data <= x"00";
when b"0010" =>
if(boundary_en_ff2 = '0') then
cnt_end_data <= x"ff";
else
cnt_end_data <= boundary_data_ff2;
end if;
when b"0100" =>
if(boundary_en_ff2 = '0') then
cnt_end_data <= boundary_data_ff2;
else
cnt_end_data <= x"00";
end if;
when b"1000" =>
if(boundary_en_ff2 = '0') then
if(reverse = '1') then
cnt_end_data <= boundary_data_ff2;
else
cnt_end_data <= x"ff";
end if;
else
if(reverse = '1') then
cnt_end_data <= x"00";
else
cnt_end_data <= boundary_data_ff2;
end if;
end if;
when others =>
cnt_end_data <= cnt_end_data;
end case;
end if;
end process;
--counter increment or decrement for each clock
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_inc <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"0001" =>
cnt_inc <= x"00";
when b"0010" =>
if(boundary_en_ff2 = '0') then
cnt_inc <= select01_boundary0_inc;
else
cnt_inc <= select01_boundary1_inc;
end if;
when b"0100" =>
if(boundary_en_ff2 = '0') then
cnt_inc <= select10_boundary0_dec;
else
cnt_inc <= select10_boundary1_dec;
end if;
when b"1000" =>
if(boundary_en_ff2 = '0') then
if(reverse = '1') then
cnt_inc <= select11_boundary0_dec;
else
cnt_inc <= select11_boundary0_inc;
end if;
else
if(reverse = '1') then
cnt_inc <= select11_boundary1_dec;
else
cnt_inc <= select11_boundary1_inc;
end if;
end if;
when others =>
cnt_inc <= cnt_inc;
end case;
end if;
end process;
--when counter increase in mode 3, get the last data that the counter can reach when counting
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_inc_end <= x"00";
elsif(rising_edge(clk_in)) then
case selector_trig is
when b"1000" =>
if(boundary_en_ff2 = '0') then
cnt_inc_end <= x"ff" - select11_boundary0_inc;
else
cnt_inc_end <= boundary_data_ff2 - select11_boundary1_inc;
end if;
when others =>
cnt_inc_end <= cnt_inc_end;
end case;
end if;
end process;
--signal to control whether it is an increment or decrement
cnt_type_1_trig <= to_stdulogic((selector_ff2 = "11" and (reverse_trig = '1' or reverse = '1')) or (selector_ff2 = "10"));
--process(cnt_type_1_trig)
--begin
-- if(cnt_type_1_trig = '1') then
-- cnt_type <= '1';
-- else
-- cnt_type <= '0';
-- end if;
--end process;
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_type <= '0';
elsif(clk_in'event and clk_in = '1') then
if(cnt_type_1_trig = '1') then
cnt_type <= '1';
else
cnt_type <= '0';
end if;
end if;
end process;
--when in mode3, reverse will be changed to 1 when counter reach to the last data when increasing
process(clk_in, rst_n)
begin
if(rst_n = '0') then
reverse <= '0';
elsif(clk_in'event and clk_in = '1') then
if(selector_trig_for_rvs /= x"0") then
reverse <= '0';
elsif(selector_ff2 = b"11") then
if(reverse = '0') then
if(cnt_out >= cnt_inc_end) then
reverse <= '1';
else
reverse <= reverse;
end if;
else
reverse <= reverse;
end if;
else
reverse <= '0';
end if;
end if;
end process;
--delay reverse one cycle
process(clk_in, rst_n)
begin
if(rst_n = '0') then
reverse_ff1 <= '0';
elsif(clk_in'event and clk_in = '1') then
reverse_ff1 <= reverse;
end if;
end process;
--find a reverse change in mode3
reverse_trig <= reverse and (not reverse_ff1);
--signal to trigger kernel counter to restart
process(clk_in, rst_n)
begin
if(rst_n = '0') then
cnt_restart <= '0';
elsif(clk_in'event and clk_in = '1') then
cnt_restart <= selector_trig(0) or selector_trig(1) or selector_trig(2) or selector_trig(3);
end if;
end process;
--send the counter data out
data <= cnt_out;
end behavioral;
--end of architecture
-----------------------------------------------------------------
--convert to segment
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity hex2segment is
generic (
M: integer := 7
);
port (
hex : in std_logic_vector(3 downto 0);
segment : out std_logic_vector(M-1 downto 0)
);
end entity hex2segment;
architecture behavioral of hex2segment is
begin
SEGMENT_WITHOUT_DP: if M=7 generate
process(hex)
begin
case hex is
--decode from hex to segment
when x"0" => segment <= b"1000000";
when x"1" => segment <= b"1111001";
when x"2" => segment <= b"0100100";
when x"3" => segment <= b"0110000";
when x"4" => segment <= b"0011001";
when x"5" => segment <= b"0010010";
when x"6" => segment <= b"0000010";
when x"7" => segment <= b"1111000";
when x"8" => segment <= b"0000000";
when x"9" => segment <= b"0010000";
when x"a" => segment <= b"0001000";
when x"b" => segment <= b"0000011";
when x"c" => segment <= b"1000110";
when x"d" => segment <= b"0100001";
when x"e" => segment <= b"0000110";
when x"f" => segment <= b"0001110";
--when in selector 1, counter should add 1 after each half second
--for other unknown selectors, set counter to 0
when others => segment <= b"1000000";
end case;
end process;
end generate SEGMENT_WITHOUT_DP;
SEGMENT_WITH_DP: if M=8 generate
process(hex)
begin
case hex is
--decode from hex to segment
when x"0" => segment <= b"11000000";
when x"1" => segment <= b"11111001";
when x"2" => segment <= b"10100100";
when x"3" => segment <= b"10110000";
when x"4" => segment <= b"10011001";
when x"5" => segment <= b"10010010";
when x"6" => segment <= b"10000010";
when x"7" => segment <= b"11111000";
when x"8" => segment <= b"10000000";
when x"9" => segment <= b"10010000";
when x"a" => segment <= b"10001000";
when x"b" => segment <= b"10000011";
when x"c" => segment <= b"11000110";
when x"d" => segment <= b"10100001";
when x"e" => segment <= b"10000110";
when x"f" => segment <= b"10001110";
--when in selector 1, counter should add 1 after each half second
--for other unknown selectors, set counter to 0
when others => segment <= b"11000000";
end case;
end process;
end generate SEGMENT_WITH_DP;
end behavioral;
-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity top is
generic (
M: integer := 7;
N: integer := 12499999
);
port (
clk : in std_logic;
rst_n : in std_logic;
selector : in std_logic_vector(1 downto 0);
boundary_en : in std_logic;
boundary_data : in std_logic_vector(7 downto 0);
data : out std_logic_vector(7 downto 0);
segment0 : out std_logic_vector(M-1 downto 0);
segment1 : out std_logic_vector(M-1 downto 0)
);
end entity top;
architecture behavioral of top is
--signal declaration in architecture
signal clk_out : std_logic;
signal data_tmp : std_logic_vector(7 downto 0);
signal hex : std_logic_vector(11 downto 0);
component clk_div is
generic (
N: integer := 12499999
);
port (
clk : in std_logic;
rst_n : in std_logic;
clk_out : out std_logic
);
end component;
component counter is
port (
clk_in : in std_logic;
rst_n : in std_logic;
selector : in std_logic_vector(1 downto 0);
boundary_en : in std_logic;
boundary_data : in std_logic_vector(7 downto 0);
data : out std_logic_vector(7 downto 0)
);
end component;
component hex2segment is
generic (
M: integer := 7
);
port (
hex : in std_logic_vector(3 downto 0);
segment : out std_logic_vector(M-1 downto 0)
);
end component;
--begin of architecture
begin
--instance clock dividor
u_clk_div: clk_div generic map (
N => N
) PORT MAP (
clk => clk ,
rst_n => rst_n ,
clk_out => clk_out
);
--instance counter
u_counter: counter PORT MAP (
clk_in => clk_out ,
rst_n => rst_n ,
selector => selector ,
boundary_en => boundary_en ,
boundary_data => boundary_data ,
data => data_tmp
);
data <= data_tmp;
--instance segment0
u_hex2segment_0: hex2segment generic map (
M => M
) PORT MAP (
hex => data_tmp(3 downto 0),
segment => segment0
);
--instance segment1
u_hex2segment_1: hex2segment generic map (
M => M
) PORT MAP (
hex => data_tmp(7 downto 4),
segment => segment1
);
end behavioral;
--end of architecture
Subscribe to:
Posts (Atom)