0% found this document useful (0 votes)
108 views23 pages

Circuit Design With VHDL - VHDL Codes

The third document describes a hamming weight calculator circuit
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
108 views23 pages

Circuit Design With VHDL - VHDL Codes

The third document describes a hamming weight calculator circuit
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 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