Circuit Design With VHDL - VHDL Codes

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 23

Example 6.3.

Registered add-and-compare circuit

1 --------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5
6 entity add_compare_registered is
7 generic (
8 NUM_BITS: natural := 8);
9 port (
10 clk: in std_logic;
11 a, b: in std_logic_vector(NUM_BITS-1 downto 0);
12 comp: out std_logic;
13 sum: out std_logic_vector(NUM_BITS downto 0));
14 end entity add_compare_registered;
15
16 architecture rtl of add_compare_registered is
17 signal a_uns, b_uns: unsigned(NUM_BITS downto 0);
18 begin
19
20 a_uns <= unsigned('0' & a);
21 b_uns <= unsigned('0' & b);
22
23 process (clk)
24 begin
25 if rising_edge(clk) then
26 if a_uns > b_uns then
27 comp <= '1';
28 else
29 comp <= '0';
30 end if;
31 sum <= std_logic_vector(a_uns + b_uns);
32 end if;
33 end process;
34
35 end architecture rtl;
36 --------------------------------------------------------------

Example 10.3. Carry-ripple adder built with full-adder components


1 --------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity full_adder_unit is
6 port (
7 in1, in2, cin: in std_logic;
8 sum, cout: out std_logic);
9 end entity;
1
0 architecture boolean of full_adder_unit is
1 begin
1 sum <= in1 xor in2 xor cin;
1 cout <= (in1 and in2) or (in1 and cin) or (in2 and cin);
2 end architecture;
1 --------------------------------------------------------------
3
1 --------------------------------------------------------------
4 library ieee;
1 use ieee.std_logic_1164.all;
5
1 entity carry_ripple_adder is
6 generic (
NUM_BITS: natural := 8);
1 port (
2 a, b: in std_logic_vector(NUM_BITS-1 downto 0);
3 cin: in std_logic;
4 sum: out std_logic_vector(NUM_BITS-1 downto 0);
5 cout: out std_logic);
6 end entity;
7
8 architecture structural of carry_ripple_adder is
9 signal carry: std_logic_vector(0 to NUM_BITS);
1 begin
0 carry(0) <= cin;
1 gen_adder: for i in 0 to NUM_BITS-1 generate
1 adder: entity work.full_adder_unit
1 port map (a(i), b(i), carry(i), sum(i), carry(i+1));
2 end generate;
1 cout <= carry(NUM_BITS);
3 end architecture;
1 --------------------------------------------------------------
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5

Example 10.4. Hamming-weight calculator

1 ----------------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5
6 entity hamming_weight_calculator is
7 generic (
8 BITS_IN: positive := 16;
9 BITS_OUT: positive := 5); --calculated by user as ceil(log2(BITS_IN+1))
1 port (
0 inp_vector: in std_logic_vector(BITS_IN-1 downto 0);
1 hamm_weight: out std_logic_vector(BITS_OUT-1 downto 0));
1 end entity;
1
2 architecture concurrent of hamming_weight_calculator is
1 type integer_array is array (0 to BITS_IN) of integer range 0 to BITS_IN;
3 signal internal: integer_array;
1 begin
4 internal(0) <= 0;
1 gen: for i in 1 to BITS_IN generate
5 internal(i) <= internal(i-1) + 1 when inp_vector(i-1) else internal(i-1);
1 end generate;
6 hamm_weight <= std_logic_vector(to_unsigned(internal(BITS_IN), BITS_OUT));
1 end architecture;
7 ----------------------------------------------------------------------------------
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5

use ieee.math_real.all;
...
generic (
BITS_IN: positive := 16;
BITS_OUT: positive := integer(ceil(log2(real(BITS_IN+1))))); --a dependent constant
port (...

entity hamming_weight_calculator is
generic (
BITS_IN: positive := 16);
port (
inp_vector: in std_logic_vector(BITS_IN-1 downto 0);
hamm_weight: out std_logic_vector(integer(ceil(log2(real(BITS_IN+1))))-1 downto 0)));
end entity;

architecture concurrent of hamming_weight_calculator is


constant BITS_OUT: positive := integer(ceil(log2(real(BITS_IN+1))));
...

Example 10.5. Signed integer adder

1 ----------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5
6 entity adder_signed is
7 generic (
8 NUM_BITS: integer := 4);
9 port (
1 a, b: in std_logic_vector(NUM_BITS-1 downto 0);
0 cin: in std_logic;
1 sum: out std_logic_vector(NUM_BITS-1 downto 0);
1 sumMSB, cout, oflow: out std_logic);
1 end entity;
2
1 architecture suggested of adder_signed is
3 signal sum_sig: signed(NUM_BITS downto 0);
1 begin
4
1 --Sign-extension, conversion to signed, and addition:
5 sum_sig <= signed(a(NUM_BITS-1) & a) + signed(b) + cin;
1 --sum_sig <= resize(signed(a), NUM_BITS+1) + signed(b) + cin;
6
1 --Conversion to std_logic_vector and final operations:
7 sum <= std_logic_vector(sum_sig(NUM_BITS-1 downto 0));
1 sumMSB <= sum_sig(NUM_BITS);
8 cout <= a(NUM_BITS-1) xor b(NUM_BITS-1) xor sumMSB;
1 oflow <= sum_sig(NUM_BITS) xor sum_sig(NUM_BITS-1);
9
2 end architecture;
0 ----------------------------------------------------------------
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1

Example 11.2. Programmable combinational delay line (structural)

1 --The component (delay block)


2 ----------------------------------------------------------------
3 library ieee;
4 use ieee.std_logic_1164.all;
5
6 entity delay_block is
7 generic (
8 BLOCK_LENGTH: natural);
9 port (
10 din: in std_logic;
11 sel: in std_logic;
12 dout: out std_logic);
13 end entity;
14
15 architecture delay_block of delay_block is
16 signal node_vector: std_logic_vector(0 to 2*BLOCK_LENGTH);
17 attribute keep: boolean;
18 attribute keep of node_vector: signal is true;
19 begin
20 node_vector(0) <= din;
21 gen: for i in 1 to 2*BLOCK_LENGTH generate
22 node_vector(i) <= not node_vector(i-1);
23 end generate;
24 dout <= node_vector(2*BLOCK_LENGTH) when sel else din;
25 end architecture;
26 ----------------------------------------------------------------

1 --Main code (complete delay line)


2 ----------------------------------------------------------------
3 library ieee;
4 use ieee.std_logic_1164.all;
5
6 entity delay_line is
7 generic (
8 NUM_BLOCKS: natural := 4); --this is M in figure 11.2b
9 port (
10 din: in std_logic;
11 --sel: in std_logic_vector(0 to NUM_BLOCKS-1);
12 sel: in std_logic_vector(NUM_BLOCKS-1 downto 0);
13 dout: out std_logic);
14 end entity;
15
16 architecture structural of delay_line is
17 signal node_vector: std_logic_vector(0 to NUM_BLOCKS);
18 attribute keep: boolean;
19 attribute keep of node_vector: signal is true;
20 begin
21 node_vector(0) <= din;
22 gen: for i in 1 to NUM_BLOCKS generate
23 blocki: entity work.delay_block
24 generic map (2**(i-1))
25 port map (node_vector(i-1), sel(i-1), node_vector(i));
26 end generate;
27 dout <= node_vector(NUM_BLOCKS);
28 end architecture;
29 ----------------------------------------------------------------

Example 12.3. Counter with is_max flag and RTL analysis

1 ----------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5
6 entity counter_with_is_max_flag is
7 generic (
8 MAX: natural := 6;
9 BITS: natural := 3); --not independent (see section 6.7)
10 port (
11 clk: in std_logic;
12 count: out std_logic_vector(BITS-1 downto 0);
13 is_max: out std_logic);
14 end entity;
15
16 architecture rtl of counter_with_is_max_flag is
17 signal i: natural range 0 to MAX;
18 begin
19
20 P1: process (clk)
21 begin
22 if rising_edge(clk) then
23 if i=MAX-1 then
24 is_max <= '1';
25 i <= i + 1;
26 elsif i=MAX then
27 is_max <= '0';
28 i <= 0;
29 else
30 i <= i + 1;
31 end if;
32 end if;
33 end process;
34 count <= std_logic_vector(to_unsigned(i, BITS));
35
36 end architecture;
37 ----------------------------------------------------------------

20 P2: process (clk)


21 begin
22 if rising_edge(clk) then
23
24 --Counter:
25 if i /= MAX then
26 i <= i + 1;
27 else
28 i <= 0;
29 end if;
30
31 --Flag generator:
32 if i=MAX-1 then
33 is_max <= '1';
34 else
35 is_max <= '0';
36 end if;
37
38 end if;
39 end process;

Example 12.4. Counters with signal and variable

1 --------------------------------------------------
2 entity dual_counter is
3 port (
4 clk: in bit;
5 count1, count2: out natural range 0 to 10);
6 end entity;
7
8 architecture rtl of dual_counter is
9 begin
10
11 counter1: process (clk)
12 begin
13 if clk'event and clk='1' then
14 count1 <= count1 + 1;
15 if count1=10 then
16 count1 <= 0;
17 end if;
18 end if;
19 end process counter1;
20
21 counter2: process (clk)
22 variable var: natural range 0 to 10;
23 begin
24 if clk'event and clk='1' then
25 var := var + 1;
26 if var=10 then
27 var := 0;
28 end if;
29 end if;
30 count2 <= var;
31 end process counter2;
32
33 end architecture;
34 --------------------------------------------------
Example 12.10. Recommended shift register implementation

1 ----------------------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity shift_register is
6 generic (
7 NUM_BITS: natural := 8;
8 NUM_STAGES: natural := 4);
9 port (
10 clk: in std_logic;
11 din: in std_logic_vector(NUM_BITS-1 downto 0);
12 dout: out std_logic_vector(NUM_BITS-1 downto 0));
13 end entity;
14
15 architecture recommended of shift_register is
16 type slv_array is array (0 to NUM_STAGES-1) of std_logic_vector(NUM_BITS-1 downto 0);
17 signal q: slv_array;
18 begin
19
20 process (clk)
21 begin
22 if rising_edge(clk) then
23 q <= din & q(0 to NUM_STAGES-2);
24 end if;
25 dout <= q(NUM_STAGES-1);
26 end process;
27
28 end architecture;
29 ----------------------------------------------------------------------------------------

Example 13.1. Generic tree-type adder array

1 -------------------------------------------------------------
2 library ieee;
3 use ieee.numeric_std.all;
4 package user_defined_type_pkg is
5 type signed_vector is array (natural range <>) of signed;
6 end package;
7 -------------------------------------------------------------

1 ----------------------------------------------------------------------------------------
2 library ieee;
3 use ieee.numeric_std.all;
4 use ieee.math_real.all;
5 use work.user_defined_type_pkg.all;
6
7 entity adder_array_generic_tree is
8 generic (
9 NUM_INPUTS: natural := 10;
10 NUM_BITS: natural := 7);
11 port (
12 x: in signed_vector(0 to NUM_INPUTS-1)(NUM_BITS-1 downto 0);
13 sum: out signed(NUM_BITS+integer(ceil(log2(real(NUM_INPUTS))))-1 downto 0));
14 end entity;
15
16 architecture tree_type_generic of adder_array_generic_tree is
17 constant LAYERS: natural := integer(ceil(log2(real(NUM_INPUTS))));
18 constant PWR_OF_TWO: natural := 2**LAYERS;
19 alias EXTRA_BITS: natural is LAYERS;
20 begin
21
22 process (all)
23 variable accum: signed_vector(0 to PWR_OF_TWO-1)(NUM_BITS+EXTRA_BITS-1 downto 0);
24 begin
25
26 --Initialization:
27 loop1: for i in 0 to NUM_INPUTS-1 loop
28 accum(i) := resize(x(i), NUM_BITS+EXTRA_BITS);
29 end loop loop1;
30 accum(NUM_INPUTS to PWR_OF_TWO-1) := (others => (others => '0'));
31
32 --Generic tree-type adder array:
33 loop3: for j in 1 to LAYERS loop
34 loop4: for i in 0 to PWR_OF_TWO/(2**j)-1 loop
35 accum(i) := accum(2*i) + accum(2*i+1);
36 end loop loop4;
37 end loop loop3;
38 sum <= accum(0);
39
40 end process;
41
42
43 end architecture;
----------------------------------------------------------------------------------------

Example 13.2. Single-switch debouncer

1 ----------------------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5 use ieee.math_real.all;
6
7 entity debouncer is
8 generic (
9 T_DEB_MS: natural := 25; --minimum debounce time in ms
10 F_CLK_KHZ: natural := 50_000); --clock frequency in kHz
11 port (
12 x, clk: in std_logic;
13 y: out std_logic);
14 end entity;
15
16 architecture single_switch of debouncer is
17 constant COUNTER_BITS: natural := 1 + integer(ceil(log2(real(T_DEB_MS*F_CLK_KHZ))));
18 signal x_reg: std_logic;
19 begin
20
21 process (clk)
22 variable count: unsigned(COUNTER_BITS-1 downto 0);
23 begin
24
25 --Timer (with input register):
26 if rising_edge(clk) then
27 x_reg <= x;
28 if y=x_reg then
29 count := (others => '0');
30 else
31 count := count + 1;
32 end if;
33 end if;
34
35 --Output register:
36 if falling_edge(clk) then
37 if count(COUNTER_BITS-1) then
38 y <= not y;
39 end if;
40 end if;
41
42 end process;
43
44 end architecture;
45 ----------------------------------------------------------------------------------------

Example 14.2. Function ceil_log2 in a package

1 ----------------------------------------------------------
2 package subprograms_pkg is
3 function ceil_log2 (input: positive) return natural;
4 end package;
5
6 package body subprograms_pkg is
7 function ceil_log2 (input: positive) return natural is
8 variable result: natural := 0;
9 begin
10 while 2**result < input loop
11 result := result + 1;
12 end loop;
13 return result;
14 end function ceil_log2;
15 end package body;
16 ----------------------------------------------------------

1 ----------------------------------------------------------
2 use work.subprograms_pkg.all;
3
4 entity test_circuit is
5 generic (
6 BITS: natural := 8);
7 port (
8 inp: in positive range 1 to 2**BITS-1;
9 outp: out natural range 0 to BITS);
10 end entity;
11
12 architecture test_circuit of test_circuit is
13 begin
14 outp <= ceil_log2(inp);
15 end architecture;
16 ----------------------------------------------------------

Example 14.4. Function slv_to_integer in a process

1 ---------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity test_circuit is
6 generic (
7 WIDTH: natural := 8);
8 port (
9 clk: in std_logic;
10 inp: in std_logic_vector(WIDTH-1 downto 0);
11 outp: out integer range 0 to 2**WIDTH-1);
12 end entity;
13
14 architecture test_circuit of test_circuit is
15 begin
16
17 process
18 function slv_to_integer (slv: std_logic_vector) return integer is
19 variable result: integer range 0 to 2**slv'length-1 := 0;
20 begin
21 for i in slv'range loop
22 result := result*2;
23 if slv(i)='1' or slv(i)='H' then
24 result := result + 1;
25 end if;
26 end loop;
27 return result;
28 end function slv_to_integer;
29 begin
30 wait until clk;
31 outp <= slv_to_integer(inp);
32 end process;
33
34 end architecture;
35 ---------------------------------------------------------------------------

Example 16.2. Garage door controller


1 ---------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity garage_door_controller is
6 port (
7 clk, rst: in std_logic;
8 remote, door_closed, door_open: in std_logic;
9 motor, direction: out std_logic);
10 end entity;
11
12 architecture fsm of garage_door_controller is
13 type state_type is (ready_to_open, opening1, opening2,
14 opening3, ready_to_close, closing1, closing2, closing3);
15 signal state: state_type;
16 begin
17
18 --Logic + register for state:
19 process (clk, rst)
20 begin
21 if rst then
22 state <= ready_to_open;
23 elsif rising_edge(clk) then
24 case state is
25 when ready_to_open =>
26 if door_open then
27 state <= ready_to_close;
28 elsif remote then
29 state <= opening1;
30 else
31 state <= ready_to_open;
32 end if;
33 when opening1 =>
34 if not remote then
35 state <= opening2;
36 else
37 state <= opening1;
38 end if;
39 when opening2 =>
40 if door_open then
41 state <= ready_to_close;
42 elsif remote then
43 state <= opening3;
44 else
45 state <= opening2;
46 end if;
47 when opening3 =>
48 ...
49 when ready_to_close =>
50 ...
51 when closing1 =>
52 ...
53 when closing2 =>
54 ...
55 when closing3 =>
56 ...
57 end case;
58 end if;
59 end process;
60
61 --Logic + register for outputs:
62 process (clk)
63 begin
64 if rising_edge(clk) then
65 case state is
66 when ready_to_open =>
67 motor <= '0';
68 direction <= '-';
69 when opening1 =>
70 motor <= '1';
71 direction <= '1';
72 when opening2 =>
73 motor <= '1';
74 direction <= '1';
75 when opening3 =>
76 motor <= '0';
77 direction <= '-';
78 when ready_to_close =>
79 motor <= '0';
80 direction <= '-';
81 when closing1 =>
82 motor <= '1';
83 direction <= '0';
84 when closing2 =>
85 motor <= '1';
86 direction <= '0';
87 when closing3 =>
88 motor <= '0';
89 direction <= '-';
90 end case;
91 end if;
92 end process;
93
94 --Notice that default values could have been used in the process above
95
96 end architecture;
97 ---------------------------------------------------------------------------

Example 16.4. SPI interface for an A/D converter


1 --------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity SPI_interface_for_MAX1118 is
6 port (
7 clk, rst: in std_logic;
8 rd: in std_logic;
9 SSn, SCLK: out std_logic;
10 MISO: in std_logic;
11 received_data: out std_logic_vector(7 downto 0));
12 end entity;
13
14 architecture fsm of SPI_interface_for_MAX1118 is
15 signal clk_5MHz: std_logic;
16 type state_type is (idle, convert, read_data, hold);
17 signal pr_state, nx_state: state_type;
18 signal t, tmax: natural range 0 to 37;
19 begin
20
21 --Generate SPI clock (5 MHz):
22 process (clk)
23 variable count: natural range 0 to 4;
24 begin
25 if rising_edge(clk) then
26 if count=4 then
27 clk_5MHz <= not clk_5MHz;
28 count := 0;
29 else
30 count := count + 1;
31 end if;
32 end if;
33 end process;
34
35 --Register for machine state:
36 process (clk_5MHz, rst)
37 begin
38 if rst then
39 pr_state <= idle;
40 elsif rising_edge(clk_5MHz) then
41 pr_state <= nx_state;
42 end if;
43 end process;
44
45 --Logic for machine state:
46 process (all)
47 begin
48 case pr_state is
49 when idle =>
50 if rd then
51 nx_state <= convert;
52 else
53 nx_state <= idle;
54 end if;
55 when convert =>
56 if t=tmax then
57 nx_state <= read_data;
58 else
59 nx_state <= convert;
60 end if;
61 when read_data =>
62 if t=tmax then
63 nx_state <= hold;
64 else
65 nx_state <= read_data;
66 end if;
67 when hold =>
68 if not rd then
69 nx_state <= idle;
70 else
71 nx_state <= hold;
72 end if;
73 end case;
74 end process;
75
76 --Logic for machine outputs:
77 process (all)
78 begin
79 case pr_state is
80 when idle =>
81 SSn <= '1';
82 SCLK <= '1';
83 when convert =>
84 SSn <= '0';
85 SCLK <= '1';
86 when read_data =>
87 SSn <= '0';
88 SCLK <= clk_5MHz;
89 when hold =>
90 SSn <= '1';
91 SCLK <= '1';
92 end case;
93 end process;
94
95 --Store data read from ADC:
96 process (clk_5MHz)
97 begin
98 if rising_edge(clk_5MHz) then
99 if pr_state = read_data then
10 received_data(7-t) <= MISO;
0 end if;
10 end if;
1 end process;
10
2 --Timer:
10 process (all)
3 begin
10 case pr_state is
4 when convert => tmax <= 37;
10 when read_data => tmax <= 7;
5 when others => tmax <= 0;
10 end case;
6 if rising_edge(clk_5MHz) then
10 if pr_state /= nx_state then
7 t <= 0;
10 elsif t /= tmax then
8 t <= t + 1;
10 end if;
9 end if;
11 end process;
0
11 end architecture;
1 --------------------------------------------------------------------------
11
2
11
3
11
4
11
5
11
6
11
7
11
8
11
9
12
0
12
1
12
2
12
3

Example 17.1. SPI Interface for an EEPROM Device (with FSM)

1 -----------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity SPI_interface_for_EEPROM is
6 generic (
7 WREN_OPCODE: std_logic_vector(7 downto 0) := "00000110";
8 WRITE_OPCODE: std_logic_vector(7 downto 0) := "00000010";
9 READ_OPCODE: std_logic_vector(7 downto 0) := "00000011";
10 INITIAL_WRITE_ADDR: std_logic_vector(15 downto 0) := (others => '0');
11 INITIAL_READ_ADDR: std_logic_vector(15 downto 0) := (others => '0'));
12 port (
13 clk, rst: in std_logic;
14 wr, rd: in std_logic;
15 SSn: out std_logic;
16 SCLK: out std_logic;
17 MOSI: out std_logic;
18 MISO: in std_logic;
19 data_read_from_EEPROM: out std_logic_vector(7 downto 0));
20 end entity;
21
22 architecture fsm of SPI_interface_for_EEPROM is
23
24 --Reference clock (12.5 MHz):
25 signal clk_12MHz: std_logic;
26
27 --FSM-related declarations:
28 type state_type is (idle, WREN_OP, deselect1, deselect2, WRITE_OP,
29 initial_wr_addr, write_data, wait_wr_low, READ_OP, initial_rd_addr,
30 read_data, wait_rd_low);
31 signal pr_state, nx_state: state_type;
32
33
34 --Timer-related declarations:
35 signal i, imax: natural range 0 to 15;
signal j, jmax: natural range 0 to 4;
36
37 --Test data (to be written to and read from EEPROM):
38 type data_array is array (natural range <>) of std_logic_vector;
39 constant test_data_out: data_array(0 to 4)(7 downto 0) :=
40 ("00000001", "10000000", "00111100", "11000011", "11111111");
41 signal test_data_in: data_array(0 to 4)(7 downto 0);
42
43
44 begin
45
46 --Generate SPI clock (12.5MHz) from system clock (50MHz):
47 process (clk)
48 variable count: natural range 0 to 1;
49 begin
50 if rising_edge(clk) then
51 if count=1 then
52 clk_12MHz <= not clk_12MHz;
53 count := 0;
54 else
55 count := count + 1;
56 end if;
57 end if;
58 end process;
59
60 --Dual timer (i=primary, j=secondary):
61 process (all)
62 begin
63 --Define imax and jmax values:
64 case pr_state is
65 when WREN_OP | WRITE_OP | write_data | READ_OP | read_data => imax <= 7;
66 when initial_wr_addr | initial_rd_addr => imax <= 15;
67 when others => imax <= 0;
68 end case;
69 case pr_state is
70 when write_data | read_data => jmax <= 4;
71 when others => jmax <= 0;
72 end case;
73 --Implement pointers i and j:
74 if rst then
75 i <= 0;
76 j <= 0;
77 elsif falling_edge(clk_12MHz) then
78 if pr_state /= nx_state then
79 i <= 0;
80 j <= 0;
81 elsif not (i=imax and j=jmax) then
82 if i/=imax then
83 i <= i + 1;
84 elsif j/=jmax then
85 i <= 0;
86 j <= j + 1;
87 end if;
88 end if;
89 end if;
90 end process;
91
92 --State register (block R1 of figure 15.2b):
93 process (clk_12MHz, rst)
94 begin
95 if rst then
96 pr_state <= idle;
97 elsif falling_edge(clk_12MHz) then
98 pr_state <= nx_state;
99 end if;
10 end process;
0
10
--State logic (block L1 of figure 15.2b):
1
process (all)
10
begin
2
case pr_state is
10
when idle =>
3
if wr and not rd then
10 nx_state <= WREN_OP;
4 elsif rd and not wr then
10 nx_state <= READ_OP;
5 else
10 nx_state <= idle;
6 end if;
10 when WREN_OP =>
7 if i=imax then
10 nx_state <= deselect1;
8 else
10 nx_state <= WREN_OP;
9 end if;
11 when deselect1 =>
0 nx_state <= deselect2;
11 when deselect2 =>
1 nx_state <= WRITE_OP;
11 when WRITE_OP =>
2 if i=imax then
11 nx_state <= initial_wr_addr;
3 else
11 nx_state <= WRITE_OP;
4 end if;
11 when initial_wr_addr =>
5 ...
11 when write_data =>
6 ...
11 when wait_wr_low =>
7 ...
11 when READ_OP =>
8 ...
11 when initial_rd_addr =>
9 ...
12 when read_data =>
0 ...
12 when wait_rd_low =>
1 ...
12 end case;
2 end process;
12
3 --Output logic (block L2' of figure 15.2b):
12 process (all)
4 begin
12 --Default values:
5 SSn <= '0';
12 SCLK <= clk_12MHz;
6 MOSI <= '-';
12 --Other values:
7 case pr_state is
12 when idle =>
8 SSn <= '1';
12 SCLK <= '0';
9 when WREN_OP =>
13 MOSI <= WREN_OPCODE(7-i);
0 when deselect1 =>
13 SCLK <= '0';
1 when deselect2 =>
13 SSn <= '1';
2 SCLK <= '0';
13 when WRITE_OP =>
3 MOSI <= WRITE_OPCODE(7-i);
13 when initial_wr_addr =>
4 MOSI <= INITIAL_WRITE_ADDR(15-i);
13 when write_data =>
5 MOSI <= test_data_out(j)(7-i);
13 when wait_wr_low =>
6 SCLK <= '0';
13 when READ_OP =>
7 MOSI <= READ_OPCODE(7-i);
13 when initial_rd_addr =>
8 MOSI <= INITIAL_READ_ADDR(15-i);
13 when wait_rd_low =>
9 SCLK <= '0';
14 end case;
0 end process;
14
1 --Store data read from EEPROM:
14 process (clk_12MHz)
2 begin
14 if rising_edge(clk_12MHz) then
3 if pr_state=read_data then
14 test_data_in(j)(7-i) <= MISO;
4 end if;
14 end if;
5 end process;
14
6
14 --Display data read from EEPROM (test circuit @1Hz):
7 process (clk_12MHz)
14 variable count1: natural range 0 to 12_500_000;
8 variable count2: natural range 0 to 4;
14 begin
9 if falling_edge(clk_12MHz) then
15 if pr_state=idle then
0 if count1=12_500_000 then
15 count1 := 0;
1 if count2 /= 4 then
15 count2 := count2 + 1;
2 else
15 count2 := 0;
3 end if;
15 else
4 count1 := count1 + 1;
15 end if;
5 data_read_from_EEPROM <= test_data_in(count2);
15 end if;
6 end if;
15 end process;
7
15 end architecture;
8 -----------------------------------------------------------------------------
15
9
16
0
16
1
16
2
16
3
16
4
16
5
16
6
16
7
16
8
16
9
17
0
17
1
17
2
17
3
17
4
17
5
17
6
17
7
17
8
17
9
18
0
18
1
18
2
18
3
18
4
18
5
18
6
18
7
18
8
18
9
19
0
19
1
19
2
19
3
19
4
19
5
19
6
19
7
19
8
19
9
20
0
20
1
20
2
20
3
20
4
20
5
20
6
20
7
20
8
20
9
21
0
21
1
21
2
21
3
21
4
21
5

Example 17.3. I2C Interface for an A/D Converter (with Pointer)

1 ---------------------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity I2C_interface is
6 generic (
7 SLAVE_ADDRESS: std_logic_vector(6 downto 0) := "0110110";
8 SETUP_REGISTER: std_logic_vector(7 downto 0) := "1101001-";
9 CONFIG_REGISTER: std_logic_vector(7 downto 0) := "011---01");
10 port (
11 clk, rst: in std_logic;
12 wr, rd: in std_logic;
13 SCL: out std_logic;
14 SDA: inout std_logic;
15 received_data: out std_logic_vector(9 downto 0));
16 end entity;
17
18 architecture fsm of I2C_interface is
19 signal clk_400kHz: std_logic; --reference clock
20 signal i: natural range 0 to 34; --pointer
21 signal wr_enable, rd_enable: std_logic;
22 begin
23
24 --Generate 400kHz from 50MHz system clock:
25 process (clk)
26 variable count: natural range 0 to 62;
27 begin
28 if rising_edge(clk) then
29 if count=62 then
30 clk_400kHz <= not clk_400kHz;
31 count := 0;
32 else
33 count := count + 1;
34 end if;
35 end if;
36 end process;
37
38 --Generate pointer and enable signals:
39 process (clk_400kHz, rst)
40 begin
41 if rst then
42 wr_enable <= '0';
43 rd_enable <= '0';
44 i <= 0;
45 elsif falling_edge(clk_400kHz) then
46 if (wr and not rd_enable) or wr_enable then
47 if i<30 then
48 wr_enable <= '1';
49 i <= i + 1;
50 elsif not wr then
51 wr_enable <= '0';
52 i <= 0;
53 end if;
54 elsif (rd and not wr_enable) or rd_enable then
55 if i<34 then
56 rd_enable <= '1';
57 i <= i + 1;
58 elsif not rd then
59 rd_enable <= '0';
60 i <= 0;
61 end if;
62 else
63 wr_enable <= '0';
64 rd_enable <= '0';
65 i <= 0;
66 end if;
67 end if;
68 end process;
69
70 --Generate SCL and SDA signals:
71 process (all)
72 begin
73
74
75 if wr_enable then
76 --Define SCL for writing:
77 case i is
78 when 1 | 30 => SCL <= '1';
79 when others => SCL <= clk_400kHz;
80 end case;
81 --Define SDA for writing:
82 case i is
83 --Start:
84 when 1 => SDA <= '0';
85 --Slave address to write:
86 when 2 to 8 => SDA <= SLAVE_ADDRESS(8-i);
87 when 9 => SDA <= '0';
88 when 10 => SDA <= 'Z';
89 --Setup register:
90 when 11 to 18 => SDA <= SETUP_REGISTER(18-i);
91 when 19 => SDA <= 'Z';
92 --Configuration register:
93 when 20 to 27 => SDA <= CONFIG_REGISTER(27-i);
94 when 28 => SDA <= 'Z';
95 --Stop:
96 when 29 => SDA <= '0';
97 when others => SDA <= '1';
98 end case;
99
10 elsif rd_enable then
0 --Define SCL for reading:
10 case i is
1 when 1 | 34 => SCL <= '1';
10 when 11 to 14 => SCL <= '0';
2 when others => SCL <= clk_400kHz;
10 end case;
3 --Define SDA for reading:
10 case i is
4 --Start:
10 when 1 => SDA <= '0';
5 --Slave address to read:
10 when 2 to 8 => SDA <= SLAVE_ADDRESS(8-i);
6 when 9 => SDA <= '1';
10 when 10 => SDA <= 'Z';
7 --Clock stretch:
10 when 11 to 14 => SDA <= 'Z';
8 --Read result byte 1:
10 when 15 to 22 => SDA <= 'Z';
9 when 23 => SDA <= '0';
11 --Read result byte 0:
0 when 24 to 31 => SDA <= 'Z';
11 when 32 => SDA <= '1';
1 --Stop:
11 when 33 => SDA <= '0';
2 when others => SDA <= '1';
11 end case;
3
11 else
4 SCL <= '1';
11 SDA <= '1';
5 end if;
11
6 end process;
11
7 --Store data read from ADC:
11 process (clk_400kHz)
8 begin
11 if rising_edge(clk_400kHz) then
9 if rd_enable then
12 if i=21 then
0 received_data(9) <= SDA;
12 elsif i=22 then
1 received_data(8) <= SDA;
12 elsif i>23 and i<32 then
2 received_data(31-i) <= SDA;
12 end if;
3 end if;
12 end if;
4 end process;
12
5
12 end architecture;
6 ---------------------------------------------------------------------------
12
7
12
8
12
9
13
0
13
1
13
2
13
3
13
4
13
5
13
6
13
7
13
8
13
9
14
0
14
1
14
2
14
3
14
4
14
5
14
6
14
7
14
8
14
9
15
0
15
1
Example 17.6. VGA Video Interface for a Hardware-Generated Image

1 ------------------------------------------------------------
2 library ieee;
3 use ieee.std_logic_1164.all;
4
5 entity image_generator_plus_vga_interface is
6 generic (
7 H_LOW: natural := 96;
8 HBP: natural := 48;
9 H_HIGH: natural := 640;
10 HFP: natural := 16;
11 V_LOW: natural := 2;
12 VBP: natural := 33;
13 V_HIGH: natural := 480;
14 VFP: natural := 10);
15 port (
16 clk: in std_logic; --50MHz system clock
17 clk_vga: out std_logic; --25MHz pixel clock
18 R_switch, G_switch, B_switch: in std_logic;
19 Hsync, Vsync: out std_logic;
20 R, G, B: out std_logic_vector(9 downto 0);
21 BLANKn, SYNCn : out std_logic);
22 end entity;
23
24 architecture rtl of image_generator_plus_vga_interface is
25 signal Hactive, Vactive, dena: std_logic;
26 begin
27
28 --CIRCUIT 1: CONTROL GENERATOR
29
30 --Static signals for DAC:
31 BLANKn <= '1'; --no blanking
32 SYNCn <= '0'; --no sync on green
33
34 --Create VGA clock (50MHz -> 25MHz):
35 process (clk)
36 begin
37 if rising_edge(clk) then
38 clk_vga <= not clk_vga;
39 end if;
40 end process;
41
42 --Create horizontal signals:
43 process (clk_vga)
44 variable Hcount: natural range 0 to H_LOW + HBP + H_HIGH + HFP;
45 begin
46 if rising_edge(clk_vga) then
47 Hcount := Hcount + 1;
48 if Hcount = H_LOW then
49 Hsync <= '1';
50 elsif Hcount = H_LOW + HBP then
51 Hactive <= '1';
52 elsif Hcount = H_LOW + HBP + H_HIGH then
53 Hactive <= '0';
54 elsif Hcount = H_LOW + HBP + H_HIGH + HFP then
55 Hsync <= '0';
56 Hcount := 0;
57 end if;
58 end if;
59 end process;
60
61 --Create vertical signals:
62 process (Hsync)
63 variable Vcount: natural range 0 to V_LOW + VBP + V_HIGH + VFP;
64 begin
65 if rising_edge(Hsync) then
66 Vcount := Vcount + 1;
67 if Vcount = V_LOW then
68 Vsync <= '1';
69 elsif Vcount = V_LOW + VBP then
70 Vactive <= '1';
71 elsif Vcount = V_LOW + VBP + V_HIGH then
72 Vactive <= '0';
73 elsif Vcount = V_LOW + VBP + V_HIGH + VFP then
74 Vsync <= '0';
75 Vcount := 0;
76 end if;
77 end if;
78 end process;
79
80 --Enable diplay:
81 dena <= Hactive and Vactive;
82
83 --CIRCUIT 2: IMAGE GENERATOR
84
85 process (all)
86 variable line_count: natural range 0 to V_HIGH;
87 begin
88 if rising_edge(Hsync) then
89 if Vactive then
90 line_count := line_count + 1;
91 else
92 line_count := 0;
93 end if;
94 end if;
95 if dena then
96 case line_count is
97 when 0 =>
98 R <= (others => '1');
99 G <= (others => '0');
10 B <= (others => '0');
0 when 1 | 2 | 479 =>
10 R <= (others => '0');
1 G <= (others => '1');
10 B <= (others => '0');
2 when 3 to 5 =>
10 R <= (others => '0');
3 G <= (others => '0');
10 B <= (others => '1');
4 when others =>
10 R <= (others => R_switch);
5 G <= (others => G_switch);
10 B <= (others => B_switch);
6 end case;
10 else
7 R <= (others => '0');
10 G <= (others => '0');
8 B <= (others => '0');
10 end if;
9 end process;
11
0 end architecture;
11 ------------------------------------------------------------
1
11
2
11
3
11
4
11
5
11
6
11
7
11
8
11
9
12
0
12
1
12
2

You might also like