Thursday, 20 March 2014

VHDL code

COIN RECEIVER
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity coin_receiver is
port(clk: in bit;
reset: in bit;
coin_input: in bit_vector (3 downto 0);
total_output: out bit_vector(7 downto 0)
);
end coin_receiver;
architecture coin_arch of coin_receiver is
type statetype is
(S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,S14,S15,S16,S17,S18,S19,S20);
signal current_state,next_state: statetype;
begin
Sequential: process(reset,CLK)
begin
      if reset='1' then current_state <=S0;
elsif (CLK'event and CLK='1') then current_state <= next_state;
      end if;
      end process;
State_transition: process(current_state,coin_input)
begin
-- DEFAULT STATEMENTS GO HERE
next_state <= current_state;
case current_state is
when S0 =>
total_output <="00000000";
if coin_input ="0000" then next_state <= S0;
elsif coin_input ="0001" then next_state <= S1;
elsif coin_input ="0010" then next_state <= S2;
elsif coin_input ="0100" then next_state <= S5;
elsif coin_input ="1000" then next_state <= S10;
end if;

when S1 =>
total_output <="00001010";
if coin_input ="0000" then next_state <= S1;
elsif coin_input ="0001" then next_state <= S2;
elsif coin_input ="0010" then next_state <= S3;
elsif coin_input ="0100" then next_state <= S6;
elsif coin_input ="1000" then next_state <= S11;
end if;

when S2 =>
total_output <="00010100";
if coin_input ="0000" then next_state <= S2;
elsif coin_input ="0001" then next_state <= S3;
elsif coin_input ="0010" then next_state <= S4;
elsif coin_input ="0100" then next_state <= S7;
elsif coin_input ="1000" then next_state <= S12;
end if;

when S3 =>
total_output <="00011110";
if coin_input ="0000" then next_state <= S3;
elsif coin_input ="0001" then next_state <= S4;
elsif coin_input ="0010" then next_state <= S5;
elsif coin_input ="0100" then next_state <= S8;
elsif coin_input ="1000" then next_state <= S13;
end if;

when S4 =>
total_output <="00101000";
if coin_input ="0000" then next_state <= S4;
elsif coin_input ="0001" then next_state <= S5;
elsif coin_input ="0010" then next_state <= S6;
elsif coin_input ="0100" then next_state <= S9;
elsif coin_input ="1000" then next_state <= S14;
end if;

when S5 =>
total_output <="00110010";
if coin_input ="0000" then next_state <= S5;
elsif coin_input ="0001" then next_state <= S6;
elsif coin_input ="0010" then next_state <= S7;
elsif coin_input ="0100" then next_state <= S10;
elsif coin_input ="1000" then next_state <= S15;
end if;

when S6 =>
total_output <="00111100";
if coin_input ="0000" then next_state <= S6;
elsif coin_input ="0001" then next_state <= S7;
elsif coin_input ="0010" then next_state <= S8;
elsif coin_input ="0100" then next_state <= S11;
elsif coin_input ="1000" then next_state <= S16;

end if;

when S7 =>
total_output <="01000110";
if coin_input ="0000" then next_state <= S7;
elsif coin_input ="0001" then next_state <= S8;
elsif coin_input ="0010" then next_state <= S9;
elsif coin_input ="0100" then next_state <= S12;
elsif coin_input ="1000" then next_state <= S17;

end if;

when S8 =>
total_output <="01010000";
if coin_input ="0000" then next_state <= S8;
elsif coin_input ="0001" then next_state <= S9;
elsif coin_input ="0010" then next_state <= S10;
elsif coin_input ="0100" then next_state <= S13;
elsif coin_input ="1000" then next_state <= S18;

end if;

when S9 =>
total_output <="01011010";
if coin_input ="0000" then next_state <= S9;
elsif coin_input ="0001" then next_state <= S10;
elsif coin_input ="0010" then next_state <= S11;
elsif coin_input ="0100" then next_state <= S14;
elsif coin_input ="1000" then next_state <= S19;

end if;

when S10 =>
total_output <="01100100";
if coin_input ="0000" then next_state <= S10;
elsif coin_input ="0001" then next_state <= S11;
elsif coin_input ="0010" then next_state <= S12;
elsif coin_input ="0100" then next_state <= S15;
elsif coin_input ="1000" then next_state <= S20;

end if;

when S11 =>
total_output <="01101110";
if coin_input ="0000" then next_state <= S11;
elsif coin_input ="0001" then next_state <= S12;
elsif coin_input ="0010" then next_state <= S13;
elsif coin_input ="0100" then next_state <= S16;

end if;

when S12 =>
total_output <="01111000";
if coin_input ="0000" then next_state <= S12;
elsif coin_input ="0001" then next_state <= S13;
elsif coin_input ="0010" then next_state <= S14;
elsif coin_input ="0100" then next_state <= S17;

end if;

when S13 =>
total_output <="10000010";
if coin_input ="0000" then next_state <= S13;
elsif coin_input ="0001" then next_state <= S14;
elsif coin_input ="0010" then next_state <= S15;
elsif coin_input ="0100" then next_state <= S18;

end if;

when S14 =>
total_output <="10001100";
if coin_input ="0000" then next_state <= S14;
elsif coin_input ="0001" then next_state <= S15;
elsif coin_input ="0010" then next_state <= S16;
elsif coin_input ="0100" then next_state <= S19;

end if;

when S15 =>
total_output <="10010110";
if coin_input ="0000" then next_state <= S15;
elsif coin_input ="0001" then next_state <= S16;
elsif coin_input ="0010" then next_state <= S17;
elsif coin_input ="0100" then next_state <= S20;

end if;

when S16 =>
total_output <="10100000";
if coin_input ="0000" then next_state <= S16;
elsif coin_input ="0001" then next_state <= S17;
elsif coin_input ="0010" then next_state <= S18;

end if;

when S17 =>
total_output <="10101010";
if coin_input ="0000" then next_state <= S17;
elsif coin_input ="0001" then next_state <= S18;
elsif coin_input ="0010" then next_state <= S19;

end if;

when S18 =>
total_output <="10110100";
if coin_input ="0000" then next_state <= S18;
elsif coin_input ="0001" then next_state <= S19;
elsif coin_input ="0010" then next_state <= S20;

end if;

when S19 =>
total_output <="10111110";
if coin_input ="0000" then next_state <= S19;
elsif coin_input ="0001" then next_state <= S20;

end if;

when S20 =>
total_output <="11001000";
next_state <= S0;

 when others =>
null;

end case;
end process;
end  coin_arch;

CONTROL
library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;

entity control is
port(
D:in bit_vector(3 downto 0);
Pri: out std_logic_vector(7 downto 0));
end entity control;

architecture art of control is

begin
process(D)
begin


if (D = "1010") then Pri <= "01010000";
elsif (D = "1011") then Pri <= "01100100";
elsif (D = "1100") then Pri <= "01111000";
elsif (D = "1101") then Pri <= "10110100";
else Pri <= "00000000";
end if;



end process;

end architecture art;

DECODER FOR 7 SEGMENT
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity decoder7 is
port (
        bcd : in std_logic_vector(3 downto 0);  --BCD input
        segment7 : out std_logic_vector(6 downto 0)  -- 7 bit decoded output.
    );
end decoder7;
--'a' corresponds to MSB of segment7 and g corresponds to LSB of segment7.
architecture Behavioral of decoder7 is

begin
process (bcd)
BEGIN
case  bcd is
when "0000"=> segment7 <="0000001";  -- '0'
when "0001"=> segment7 <="1001111";  -- '1'
when "0010"=> segment7 <="0010010";  -- '2'
when "0011"=> segment7 <="0000110";  -- '3'
when "0100"=> segment7 <="1001100";  -- '4' 
when "0101"=> segment7 <="0100100";  -- '5'
when "0110"=> segment7 <="0100000";  -- '6'
when "0111"=> segment7 <="0001111";  -- '7'
when "1000"=> segment7 <="0000000";  -- '8'
when "1001"=> segment7 <="0000100";  -- '9'
when "1010"=> segment7 <="0001000";  -- 'A'
when "1011"=> segment7 <="1100000";  -- 'B'
when "1100"=> segment7 <="0110001";  -- 'C'
when "1101"=> segment7 <="1000010";  -- 'D'
 --nothing is displayed when a number more than 9 is given as input. 
when others=> segment7 <="1111111"; 
end case;

end process;

end Behavioral;

DISPLAY CONTROL
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity DisplayControl is
port(
received_quotient : in std_logic_vector(7 DOWNTO 0);
received_remain : in std_logic_vector(7 DOWNTO 0);
diff_quotient : in std_logic_vector(7 DOWNTO 0);
diff_remain : in std_logic_vector(7 DOWNTO 0);
num_50 : in std_logic_vector(3 DOWNTO 0);
num_20 : in std_logic_vector(3 DOWNTO 0);
num_10 : in std_logic_vector(3 DOWNTO 0);
keypad_data : in std_logic_vector(3 DOWNTO 0);
d1 : out std_logic_vector(3 DOWNTO 0);
d2 : out std_logic_vector(3 DOWNTO 0);
d3 : out std_logic_vector(3 DOWNTO 0);
d4 : out std_logic_vector(3 DOWNTO 0);
d5 : out std_logic_vector(3 DOWNTO 0);
d6 : out std_logic_vector(3 DOWNTO 0);
d7 : out std_logic_vector(3 DOWNTO 0);
d8 : out std_logic_vector(3 DOWNTO 0));
end DisplayControl;

architecture vend of DisplayControl is
begin
process(keypad_data,received_quotient,received_remain,diff_quotient,diff_remain,num_50,num_20,num_10)

variable received_h: integer;
variable received_l: integer;
variable diff_h: integer;
variable diff_l: integer;
variable n50: integer;
variable n20: integer;
variable n10: integer;
begin
received_h := CONV_INTEGER(received_quotient);
d1 <= CONV_STD_LOGIC_VECTOR(received_h, 4);
received_l := CONV_INTEGER(received_remain);
d2 <= CONV_STD_LOGIC_VECTOR(received_l, 4);
diff_h := CONV_INTEGER(diff_quotient);
d3 <= CONV_STD_LOGIC_VECTOR(diff_h, 4);
diff_l := CONV_INTEGER(diff_remain);
d4 <= CONV_STD_LOGIC_VECTOR(diff_l, 4);
d5 <= keypad_data;
d6 <= num_50;
d7 <= num_20;
d8 <= num_10;

end process;
end vend;

COIN RETURNER: FIFTY PENNY MODULE
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_unsigned.ALL;
entity fiftyPennyModule is
port (in1 : std_logic_vector(7 DOWNTO 0);
num_50p_returned :out std_logic_vector(3 DOWNTO 0); 
pout :out std_logic_vector(7 DOWNTO 0));
end fiftyPennyModule;

architecture func of fiftyPennyModule is
begin
process(in1)
variable left: integer;
variable right: integer;
variable result: integer;
variable num_fifty: integer;

begin
left:= CONV_INTEGER(in1);
right := 50;
num_fifty := 0;
result := 0;
if (left >= right) then 
left := left - right;
num_fifty := num_fifty + 1;
else left := left;
end if;
result := left; 
pout <= CONV_STD_LOGIC_VECTOR(result, 8);
num_50p_returned <= CONV_STD_LOGIC_VECTOR(num_fifty, 4);
end process;
end func;

COIN RETURNER: TWENTY PENNY MODULE
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_unsigned.ALL;
entity twentyPennyModule is
port (in1 : std_logic_vector(7 DOWNTO 0);
num_20p_returned :out std_logic_vector(3 DOWNTO 0); 
pout :out std_logic_vector(7 DOWNTO 0));
end twentyPennyModule;

architecture func of twentyPennyModule is
begin
process(in1)
variable left: integer;
variable right: integer;
variable result: integer;
variable num_twenty: integer;

begin
left:= CONV_INTEGER(in1);
right := 20;
num_twenty := 0;
result := 0;
if (left >= right) then 
left := left - right;
num_twenty := num_twenty + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_twenty := num_twenty + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_twenty := num_twenty + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_twenty := num_twenty + 1;
else left := left;
end if;

result := left; 
pout <= CONV_STD_LOGIC_VECTOR(result, 8);
num_20p_returned <= CONV_STD_LOGIC_VECTOR(num_twenty, 4);
end process;
end func;

COIN RETURNER: TEN PENNY MODULE
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_unsigned.ALL;
entity tenPennyModule is
port (in1 : std_logic_vector(7 DOWNTO 0);
num_10p_returned :out std_logic_vector(3 DOWNTO 0));
end tenPennyModule;

architecture func of tenPennyModule is
begin
process(in1)
variable left: integer;
variable right: integer;
variable result: integer;
variable num_ten:integer;

begin
left:= CONV_INTEGER(in1);
right := 10;
num_ten := 0;
result := 0;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;
if (left >= right) then 
left := left - right;
num_ten := num_ten + 1;
else left := left;
end if;

result := left; 

num_10p_returned <= CONV_STD_LOGIC_VECTOR(num_ten, 4);
end process;
end func;

SUBTRACOTR
library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;

entity subtracterr is
port( in1 : in std_logic_vector(7 downto 0);
in2 : in std_logic_vector(7 downto 0);
enable : in bit;
pout : out std_logic_vector(7 downto 0));
end subtracterr;


architecture func of subtracterr is 
begin
process(in1, in2)
begin
if (enable = '1') then
pout <= in1 - in2;
end if;
end process;
end func;

TRAN
library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
entity tran is
port(pri: in bit_vector(7 downto 0);
fn: out bit_vector(7 downto 0);
sn: out bit_vector(7 downto 0));
end entity tran;
architecture art of tran is
begin
process(pri)
begin
if    (pri="00001010") then fn<="00000000" ; sn<="00000001";
elsif (pri="00010100") then fn<="00000000"; sn<="00000010";
elsif (pri="00011110") then fn<="00000000"; sn<="00000011";
elsif (pri="00101000") then fn<="00000000"; sn<="00000100";
elsif (pri="00110010") then fn<="00000000"; sn<="00000101";
elsif (pri="00111100") then fn<="00000000"; sn<="00000110";
elsif (pri="01000110") then fn<="00000000"; sn<="00000111";
elsif (pri="01010000") then fn<="00000000"; sn<="00001000";
elsif (pri="01011010") then fn<="00000000"; sn<="00001001";
elsif (pri="01100100") then fn<="00000001"; sn<="00000000";
elsif (pri="01101110") then fn<="00000001"; sn<="00000001";
elsif (pri="01111000") then fn<="00000001"; sn<="00000010";
elsif (pri="10000010") then fn<="00000001"; sn<="00000011";
elsif (pri="10001100") then fn<="00000001"; sn<="00000100";
elsif (pri="10010110") then fn<="00000001"; sn<="00000101";
elsif (pri="10100000") then fn<="00000001"; sn<="00000110";
elsif (pri="10101010") then fn<="00000001"; sn<="00000111";
elsif (pri="10110100") then fn<="00000001"; sn<="00001000";
elsif (pri="10111110") then fn<="00000001"; sn<="00001001";
elsif (pri="11001000") then fn<="00000010"; sn<="00000000";
else fn<="00000000";sn<="00000000";
end if;
end process;
end architecture art;


Block Diagrams

Display control
Coin receiver
Keypad

Combination of coin receiver and returner


keypad scanner

This is the overall schematic of the final design

Friday, 28 February 2014

Fifth lab day 28-02-2014

Here is our last lab day for the project. The entire VHDL code is finished after several times of modification. The task for this week is to test the hardware (FPGA board).


Ready to use

Insert 10p

Insert 20p

Insert 50p

Insert 1Pound

Select item 'C'

Collect change

Here is the work that members have done on our fifth lab day.

Ye Zhu
I arranged files as a part of preparation for bench inspection. Apart from this, I collected and updated blogs for our group. Since there is a deadline for blog submission, I wrote the summary of the blog as the description shown on the Y2 project website, Xiaotian Zhang helped me with the summary.
Junlin Guo
Because we started the test on DE2 board, I was in charge of the simulation of coin_returner and help others to debug. Besides, I took some photo for our poster.

Friday, 21 February 2014

Fourth lab day 21-02-2014

This is our fourth lab day. After almost one month effort, we gradually made some achievements though there   were several problems during the project.
Here is several draft diagrams that we made in the last 3 weeks.
figure 1: original overall block diagram


Figure 1 is our original block diagram. However, it needs some improvements (pointed out by our supervisor).

 figure 2 :  improved block diagram
           

    figure 3 : use case diagram

Here is the work that each member done during the fourth lab day.
Ye Zhu
I drew the updated block diagram with the help of Xiaotian Zhang. Also, I started to simulate the VHDL code for coin receiver. The simulation is successful, but we can only input the coin during one clock period. We could not apply this to real vending machine. Therefore, I need to do some modification to the code in order to satisfy the requirements.

Yuhao Gu
This is the rest of my keypad, the code is almost finished, and the control and the subtracter, the control part is to select the items and to show the price, the subtracter is used to subtract the price from the insert coins. This is the block digram.

Sunday, 16 February 2014

Third lab day 14-02-2014

After 2 weeks of discussing and researching, each member has made some achievements. However, our supervisor raised some questions when we met him before starting the lab. The problem is that the overall structure is still not very clear to him. Therefore, we modified our structure and made it as a flowchart of the whole procedure.
Overall flowchart for vending machine


Here is the work that members have done on our second lab day.

Ye Zhu
I finished drawing the state diagram and block diagram of my part -- coin receiver. Then I started writing the VHDL code for coin receiver. After searching on the internet, I found some useful sources of vending machine. (Ref: J Zhang, The Design, Simulation, Verification and Implementation of Vending Machine
Based on FPGA)  I modified the code according to the source supplied.
Block diagram for coin_receiver


Junlin Guo
In the third week, I have finished the fundamental coding process for the change returner. However, we were told by the supervisor that we still need to work on the top level of design which involves making sequence diagram and overall block diagram. In my point of view, the supervisor wants us to carry out the design in a formal procedure, step by step. After this week's meeting, we need to adjusted our strategy as soon as possible. Hopefully, we can catch up the schedule in the next week.

Yuhao Gu
I finished the code for keypad, four bits cols input, four bits rows output, a valid to insure the key pressed is useful, a 4 bits output that connect to the control. This is the block digram.
Block diagram for keypad

Tuesday, 11 February 2014

Second lab day 07-02-2014

In our second lab day, we worked separately and focused on our own parts. Since we had met the supervisor for the second time, we knew how to do the work from top level. We drew the block diagram, ASM chart and state diagram of vending machine. Apart from this, some group members started researching  VHDL code and tried to write the code by themselves.

Here is the work that members have done on our second lab day.

Junlin Guo
During this week's lab session, I started to write the VHDL code for the coin returner. Firstly, I partially solved the problem that how to determine the number of each type of coin according to the change value. However, there still exists some problems. Since VHDL won't support the loop instruction for an undefined value, I have to find another way to achieve the loop function. I've finished the change function using 50p, and that of 20p is still in progress...

Ye Zhu
Since the state diagram for coin receiver is very complex (21 states, from S0 to S20). I kept on writing the state diagram and starting to draw ASM for coin receiver. I calculated that we needed 5 D-type flip-flops and we should have adder to calculate the sum of input coins D- type flip-flops to represent 5 state bits. However, there was some problems when converting ASM chart to logic circuits.

Xiaotian Zhang
Focus of this week was turned to the ASM chart and related design.

Since my work remains on LCD controller module, four states namely:

  • power_up - wait a certain period to ensure voltage has risen to proper level
  • initialize - cycle through initialization sequence
  • ready - wait for the enable signal and then latch in the instruction
  • send  - send instruction to lcd  

were designed to initialise & function the controller.
The rough code was made yet still need improvement on specific functions of LCD display.


Yuhao Gu
After know the theory of keypad, i started to write the block diagram, i firstly divide it into 3 parts, the keypad, the scanner and the decoder. There will be four scanning signals follow the order 1110-1101-1011-0111-1110. Also the key that pressed will be know by the input signal. Then, the decoder will process the signal from scanner and output a signal that can be received by 7-segment. Actually, for now, i only know how to show the key that have been pressed, but the code to control the products haven't be considered yet.


Friday, 7 February 2014

Third meeting with supervisor 03-02-2013

Since we were still confused with the project. We met the supervisor for the second time. Every group member drew the draft of their responsible parts and raised several questions according to the draft.

  • Not familiar with memory
  • do not know how to convert the output signal to something that can be distinguished by scanner
  • do not know how to add instructions (hints) after each step
  • some problem with usage of RAM on the board