슬라이드 1

11.7 FSMD Summation
2
Clock.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Clockdiv IS PORT (
Clk25Mhz: IN
STD_LOGIC;
Clk: OUT STD_LOGIC);
END Clockdiv;
ARCHITECTURE Behavior OF Clockdiv IS
-CONSTANT max: INTEGER := 1000; -- minimum to debounce switch
CONSTANT max: INTEGER := 5000000; -- good to see FSM states
-CONSTANT max: INTEGER := 10000000; -- 10000000; = 1sec
CONSTANT half: INTEGER := max/2;
SIGNAL count: INTEGER RANGE 0 TO max;
BEGIN
PROCESS
BEGIN
WAIT UNTIL Clk25Mhz'EVENT and Clk25Mhz = '1';
IF count < max THEN
count <= count + 1;
ELSE
count <= 0;
END IF;
IF count < half THEN
Clk <= '0';
ELSE
Clk <= '1';
END IF;
END PROCESS;
END Behavior;
3
Bcd.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY BCD IS PORT (
in_bcd: IN std_logic_vector(3 DOWNTO 0);
segs: OUT std_logic_vector(1 TO 7));
END BCD;
ARCHITECTURE Behavioral OF BCD IS
BEGIN
PROCESS(in_bcd)
BEGIN
CASE in_bcd IS
-- 0=on; 1=off
WHEN "0000" => segs <= "0000001";
WHEN "0001" => Segs <= "1001111";
WHEN "0010" => Segs <= "0010010";
WHEN "0011" => Segs <= "0000110";
WHEN "0100" => Segs <= "1001100";
WHEN "0101" => Segs <= "0100100";
WHEN "0110" => Segs <= "0100000";
WHEN "0111" => Segs <= "0001111";
WHEN "1000" => Segs <= "0000000";
WHEN "1001" => Segs <= "0001100";
WHEN "1010" => Segs <= "0001000";
WHEN "1011" => Segs <= "1100000";
WHEN "1100" => Segs <= "0110001";
WHEN "1101" => Segs <= "1000010";
WHEN "1110" => Segs <= "0110000";
WHEN "1111" => Segs <= "0111000";
WHEN OTHERS => Segs <= "1111111";
END CASE;
END PROCESS;
END Behavioral;
-- 0
-- 1
-- 2
-- 3
-- 4
-- 5
-- 6
-- 7
-- 8
-- 9
-- A
-- b
-- C
-- d
-- E
-- F
-- all off
4
Bin_to_bcd.vhd
IF (n >= 90) THEN
-- this program converts an 8-bit unsigned value to two BCD values
-- if number >= 200, the decimal point for the tenth digit is on
-- if 200 > number >= 100, the decimal point for the unit digit is on
-- if number < 99, the two decimal digits will be separated into two BCD values
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
-- for CONV_INTEGER()
USE IEEE.std_logic_arith.all;
-- for
CONV_STD_LOGIC_VECTOR()
ELSIF
ELSIF
ELSIF
ENTITY bin_to_bcd IS PORT (
binary: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
point200, point100: OUT STD_LOGIC;
bcd_tenth, bcd_unit: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END bin_to_bcd;
ELSIF
ELSIF
ARCHITECTURE Behavioral OF bin_to_bcd IS
BEGIN
PROCESS(binary)
VARIABLE n: integer RANGE 0 TO 255;
VARIABLE ten: integer RANGE 0 TO 99;
VARIABLE unit: integer RANGE 0 TO 9;
BEGIN
n := CONV_INTEGER(binary);
IF (n >= 200) THEN
point200 <= '1';
n := n - 100;
ELSE
point200 <= '0';
END IF;
IF (n >= 100) THEN
point100 <= '1';
n := n - 100;
ELSIF
ELSIF
ELSIF
ELSE
bcd_tenth <= "0000";
ten := 0;
END IF;
unit := n - ten;
bcd_unit <= CONV_STD_LOGIC_VECTOR(unit,4);
END Process;
ELSE
point100 <= '0';
END IF;
bcd_tenth <= "1001";
ten := 90;
(n >= 80) THEN
bcd_tenth <= "1000";
ten := 80;
(n >= 70) THEN
bcd_tenth <= "0111";
ten := 70;
(n >= 60) THEN
bcd_tenth <= "0110";
ten := 60;
(n >= 50) THEN
bcd_tenth <= "0101";
ten := 50;
(n >= 40) THEN
bcd_tenth <= "0100";
ten := 40;
(n >= 30) THEN
bcd_tenth <= "0011";
ten := 30;
(n >= 20) THEN
bcd_tenth <= "0010";
ten := 20;
(n >= 10) THEN
bcd_tenth <= "0001";
ten := 10;
END Behavioral;
5
Bin2dec.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY bin2dec IS PORT (
input: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
PointN200,PointN100: OUT STD_LOGIC;
aN10,bN10,cN10,dN10,eN10,fN10,gN10,aN1,bN1,cN1,dN1,eN1,fN
1,gN1: OUT STD_LOGIC);
END bin2dec;
ARCHITECTURE Structural OF bin2dec IS
COMPONENT bin_to_bcd PORT (
binary: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
point200, point100: OUT STD_LOGIC;
bcd_tenth, bcd_unit: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
COMPONENT BCD PORT (
in_bcd: IN std_logic_vector(3 DOWNTO 0);
segs: OUT std_logic_vector(1 TO 7));
END COMPONENT;
BEGIN
U1: bin_to_bcd PORT MAP
(input,c_point200,c_point100,c_bcd10,c_bcd1);
U2: BCD PORT MAP (c_bcd10,c_seg10);
U3: BCD PORT MAP (c_bcd1,c_seg1);
PointN200 <= NOT c_point200;
PointN100 <= NOT c_point100;
aN10 <= c_seg10(1);
bN10 <= c_seg10(2);
cN10 <= c_seg10(3);
dN10 <= c_seg10(4);
eN10 <= c_seg10(5);
fN10 <= c_seg10(6);
gN10 <= c_seg10(7);
aN1 <= c_seg1(1);
bN1 <= c_seg1(2);
cN1 <= c_seg1(3);
dN1 <= c_seg1(4);
eN1 <= c_seg1(5);
fN1 <= c_seg1(6);
gN1 <= c_seg1(7);
END Structural;
SIGNAL c_bcd1,c_bcd10: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL c_point200,c_point100: STD_LOGIC;
SIGNAL c_seg10,c_seg1: STD_LOGIC_VECTOR(1 TO 7);
6
Sum.vhd(1)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY sum IS PORT (
Clock, Reset, Start: IN STD_LOGIC;
Input: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Done: OUT STD_LOGIC;
Output: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END sum;
ARCHITECTURE FSMD OF sum IS
TYPE state_type IS (s0, s1, s2, s3, s4);
SIGNAL state: state_type;
SIGNAL sum: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL n: STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
next_state_logic: PROCESS(Reset, Clock)
BEGIN
IF(Reset = '1') THEN
state <= s0;
ELSIF(Clock'EVENT AND Clock = '1') THEN
CASE state IS
WHEN s0 =>
IF (Start = '1') THEN state <= s1; ELSE state <= s0; END IF;
sum <= (others => '0');
WHEN s1 =>
-- need to test with
Input and not n because n has not been updated yet
IF (Input /= 0) THEN state <= s2; ELSE state <= s4; END IF;
n <= Input;
WHEN s2 =>
state <= s3;
sum <= sum + n;
WHEN s3 =>
-- reading n in the following IF
statement is BEFORE the decrement
- update, therefore, we need to compare with 1 and not 0
n <= n - 1;
IF (n /= 1) THEN state <= s2; ELSE state <= s4; END IF;
WHEN s4 =>
state <= s4;
WHEN OTHERS =>
state <= s0;
END CASE;
END IF;
END PROCESS;
7
Sum.vhd(2)
output_logic: PROCESS(state)
BEGIN
CASE state IS
WHEN s4 =>
Done <= '1';
Output <= sum;
WHEN OTHERS =>
Done <= '0';
Output <= (others => 'Z');
END CASE;
END PROCESS;
END FSMD;
8
COMPONENT sum PORT (
Clock,
UP2flex.vhd
Reset, Start: IN
STD_LOGIC;
Input: IN STD_LOGIC_VECTOR(7
DOWNTO 0);
Done: OUT STD_LOGIC;
Output: OUT STD_LOGIC_VECTOR(7
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
DOWNTO 0));
END COMPONENT;
COMPONENT bin2dec PORT (
ENTITY up2flex IS PORT (
input: IN STD_LOGIC_VECTOR(7
Clock_25MHz, ResetN, StartN: IN STD_LOGIC;
DOWNTO
0);
InputN: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
PointN200,PointN100: OUT
PointN200,PointN100: OUT STD_LOGIC;
STD_LOGIC;
aN10,bN10,cN10,dN10,eN10,fN10,gN10,aN1,bN
1,cN1,dN1,eN1,fN1,gN1: OUT STD_LOGIC;
aN10,bN10,cN10,dN10,eN10,fN10,gN10,aN1,bN1,c
DoneN: OUT STD_LOGIC);
N1,dN1,eN1,fN1,gN1: OUT STD_LOGIC);
END up2flex;
END COMPONENT;
ARCHITECTURE Structural OF up2flex IS
COMPONENT ClockDiv PORT (
Clk25Mhz: IN STD_LOGIC;
Clk: OUT STD_LOGIC);
END COMPONENT;
COMPONENT sum PORT (
Clock,
Reset, Start: IN
STD_LOGIC;
Input: IN STD_LOGIC_VECTOR(7
DOWNTO 0);
Done: OUT STD_LOGIC;
Output: OUT
STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT
SIGNAL Clock, mp_Halt, mp_Reset, mp_Start:
STD_LOGIC;
SIGNAL mp_Input, mp_Output:
STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
-- doing structural modeling
mp_Reset <= NOT ResetN;
mp_Start <= NOT StartN;
mp_Input <= NOT InputN;
U0: ClockDiv PORT MAP(Clock_25MHz, Clock);
U1: sum PORT MAP(Clock, mp_Reset, mp_Start,
mp_Input, mp_Halt, mp_Output);
U2: bin2dec PORT
MAP(mp_Output,PointN200,PointN100,aN10,bN10,cN10,dN10,eN1
0,fN10,gN10,aN1,bN1,cN1,dN1,eN1,fN1,gN1);
DoneN <= NOT mp_Halt;
END Structural;
9
Up2flex.gdf
10
11
12
13
14
15
16
17
18
19
20
21
signal
pin
number
signal
pin
number
signal
pin
number
clock
Pin_91
StartN
Pin_29
ResetN
Pin_28
aN1
Pin_17
aN10
Pin_6
input(7)
Pin_41
bN1
Pin_18
bN10
Pin_7
input(6)
Pin_40
cN1
Pin_19
cN10
Pin_8
input(5)
Pin_39
dN1
Pin_20
dN10
Pin_9
input(4)
Pin_38
eN1
Pin_21
eN10
Pin_11
input(3)
Pin_36
fN1
Pin_23
fN10
Pin_12
input(2)
Pin_35
gN1
Pin_24
gN10
Pin_13
input(1)
Pin_34
pointN100
Pin_25
DoneN
Pin_14
input(0)
Pin_33
22
23
24
25
26
27
동작 순서(1)
 Input
 Reset - FLEX_PB1
 Start - FLEX_PB2
 N – FLEX_SW switch 1 to 8
 Output
 Done Signal – Decimal point on Digit 1
 Sum of n downto 1 displayed on the two 7-segment LEDs
28
동작 순서 (2)
 Reset 스위치를 누른다
 DIP 스위치의 값을 세팅한다
 예 ) 00001010(down :1)
 Start 스위치를 누른다
 N에서 1까지의 값을 합을 보여준다.
29