b7a31d7b3ac8d92ec51d4233e4689e1d60263272
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

1) LIBRARY IEEE;
2) USE IEEE.STD_LOGIC_1164.ALL;
3) USE IEEE.NUMERIC_STD.ALL;
4) 
5) ENTITY e_block_fifo IS
6)     GENERIC (
7)         addr_width: natural;
8)         data_width: natural
9)     );
10)     PORT (
11)         rst:       IN  std_logic;
12)         clk:       IN  std_logic;
13)         o_wr_rdy:  OUT std_logic;
14)         i_wr_data: IN  std_logic_vector(data_width - 1 DOWNTO 0);
15)         i_wr_en:   IN  std_logic;
16)         o_rd_rdy:  OUT std_logic;
17)         o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0);
18)         i_rd_en:   IN  std_logic
19)     );
20) END ENTITY e_block_fifo;
21) 
22) ARCHITECTURE a_block_fifo OF e_block_fifo IS
23) 
24)     COMPONENT e_block_rwram
25)         GENERIC (
26)             addr_width: natural;
27)             data_width: natural := 8
28)         );
29)         PORT (
30)             clk:       IN  std_logic;
31)             i_rd_addr: IN  std_logic_vector(addr_width - 1 DOWNTO 0);
32)             o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0);
33)             i_wr_addr: IN  std_logic_vector(addr_width - 1 DOWNTO 0);
34)             i_wr_data: IN  std_logic_vector(data_width - 1 DOWNTO 0);
35)             i_wr_en:   IN  std_logic
36)         );
37)     END COMPONENT e_block_rwram;
38) 
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

39)     SUBTYPE t_pos  IS natural RANGE 0 TO 2 ** addr_width - 1;
40)     SUBTYPE t_addr IS std_logic_vector(addr_width - 1 DOWNTO 0);
41)     SUBTYPE t_data IS std_logic_vector(data_width - 1 DOWNTO 0);
42) 
43)     SIGNAL r_begin:         t_pos     := 0;
44)     SIGNAL n_begin:         t_pos;
45)     SIGNAL s_begin_addr:    t_addr;
46)     SIGNAL s_begin_sn_addr: t_addr; -- _sn_ means sometimes next
47)     SIGNAL s_rd_rdy:        std_logic;
48)     SIGNAL s_rd_en:         std_logic;
49) 
50)     SIGNAL r_end:            t_pos     := 0;
51)     SIGNAL n_end:            t_pos;
52)     SIGNAL s_end_addr:       t_addr;
53)     SIGNAL r_end_addr_delay: t_addr := (OTHERS => '0');
54)     SIGNAL s_end_an_addr:    t_addr; -- _an_ means always next
55)     SIGNAL s_wr_rdy:         std_logic;
56)     SIGNAL s_wr_en:          std_logic;
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

57) 
58)     FUNCTION next_pos (
59)         pos: natural RANGE 0 TO 2 ** addr_width - 1
60)     ) RETURN natural IS
61)         VARIABLE v_next: natural RANGE 0 TO 2 ** addr_width - 1;
62)     BEGIN
63)         IF pos = 2 ** addr_width - 1 THEN
64)             v_next := 0;
65)         ELSE
66)             v_next := pos + 1;
67)         END IF;
68)         RETURN v_next;
69)     END FUNCTION next_pos;
70) 
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

71)     FUNCTION to_addr (
72)         pos: natural RANGE 0 TO 2 ** addr_width - 1
73)     ) RETURN std_logic_vector IS
74)     BEGIN
75)         RETURN std_logic_vector(to_unsigned(pos, addr_width));
76)     END FUNCTION to_addr;
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

77) 
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

78) BEGIN
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

79) 
80)     i_rwram: e_block_rwram
81)         GENERIC MAP (
82)             addr_width => addr_width,
83)             data_width => data_width
84)         )
85)         PORT MAP (
86)             clk       => clk,
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

87)             i_rd_addr => s_begin_sn_addr,
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

88)             o_rd_data => o_rd_data,
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

89)             i_wr_addr => s_end_addr,
90)             i_wr_data => i_wr_data,
91)             i_wr_en   => s_wr_en
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

92)         );
93) 
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

94)     s_begin_addr    <= to_addr(r_begin);
95)     s_begin_sn_addr <= to_addr(n_begin);
96)     s_rd_rdy        <= '1' WHEN s_begin_addr /= r_end_addr_delay ELSE '0';
97)     s_rd_en         <= s_rd_rdy AND i_rd_en;
98) 
99)     s_end_addr      <= to_addr(r_end);
100)     s_end_an_addr   <= to_addr(next_pos(r_end));
101)     s_wr_rdy        <= '1' WHEN s_end_an_addr /= s_begin_addr ELSE '0';
102)     s_wr_en         <= s_wr_rdy AND i_wr_en;
103) 
104)     o_wr_rdy        <= s_wr_rdy;
105)     o_rd_rdy        <= s_rd_rdy;
106) 
107)     p_next: PROCESS(r_begin, r_end, s_rd_en, s_wr_en)
108)     BEGIN
109)         n_begin <= r_begin;
110)         n_end <= r_end;
111)         IF s_rd_en = '1' THEN
112)             n_begin <= next_pos(r_begin);
113)         END IF;
114)         IF s_wr_en = '1' THEN
115)             n_end <= next_pos(r_end);
116)         END IF;
117)     END PROCESS p_next;
118) 
119)     p_sync: PROCESS(rst, clk)
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

120)     BEGIN
121)         IF rst = '1' THEN
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

122)             r_begin          <= 0;
123)             r_end            <= 0;
124)             r_end_addr_delay <= (OTHERS => '0');
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

125)         ELSIF rising_edge(clk) THEN
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

126)             r_begin          <= n_begin;
127)             r_end            <= n_end;
128)             r_end_addr_delay <= s_end_addr;
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

129)         END IF;
Stefan Schuermans improve synchonous FIFO imp...

Stefan Schuermans authored 12 years ago

130)     END PROCESS p_sync;