230fe3b7e797cce9a8a42e7b8cca5d49eb381994
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) 
39)     SUBTYPE t_addr_n 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_addr_n  := 0;
44)     SIGNAL r_end:         t_addr_n  := 0;
45)     SIGNAL r_end_dly1:    t_addr_n  := 0;
46)     SIGNAL r_end_dly2:    t_addr_n  := 0;
47)     SIGNAL r_begin_chgd:  std_logic := '0';
48)     SIGNAL r_ram_wr_addr: t_addr    := (OTHERS => '0');
49)     SIGNAL r_ram_wr_data: t_data    := (OTHERS => '0');
50)     SIGNAL r_ram_wr_en:   std_logic := '0';
51) 
52)     SIGNAL s_ram_rd_addr: t_addr;
53)     SIGNAL s_rd_rdy:      std_logic;
54)     SIGNAL s_wr_rdy:      std_logic;
55) 
56)     FUNCTION next_pos (
57)         pos: natural RANGE 0 TO 2 ** addr_width - 1
58)     ) RETURN natural IS
59)         VARIABLE v_next: natural RANGE 0 TO 2 ** addr_width - 1;
60)     BEGIN
61)         IF pos = 2 ** addr_width - 1 THEN
62)             v_next := 0;
63)         ELSE
64)             v_next := pos + 1;
65)         END IF;
66)         RETURN v_next;
67)     END FUNCTION next_pos;
68) 
69) BEGIN
70) 
71)     s_ram_rd_addr <= std_logic_vector(to_unsigned(r_begin, addr_width));
72) 
Stefan Schuermans fixed FIFO implementation

Stefan Schuermans authored 12 years ago

73)     s_rd_rdy <= '0' WHEN r_begin = r_end_dly2 OR r_begin_chgd = '1' ELSE '1';
74)     s_wr_rdy <= '0' WHEN r_begin = next_pos(r_end)                  ELSE '1';
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

75) 
76)     o_rd_rdy <= s_rd_rdy;
77)     o_wr_rdy <= s_wr_rdy;
78) 
79)     i_rwram: e_block_rwram
80)         GENERIC MAP (
81)             addr_width => addr_width,
82)             data_width => data_width
83)         )
84)         PORT MAP (
85)             clk       => clk,
86)             i_rd_addr => s_ram_rd_addr,
87)             o_rd_data => o_rd_data,
88)             i_wr_addr => r_ram_wr_addr,
89)             i_wr_data => r_ram_wr_data,
90)             i_wr_en   => r_ram_wr_en
91)         );
92) 
93)     p_fifo: PROCESS(rst, clk)
94)     BEGIN
95)         IF rst = '1' THEN
96)             r_begin       <= 0;
97)             r_end         <= 0;
98)             r_end_dly1    <= 0;
99)             r_end_dly2    <= 0;
100)             r_begin_chgd  <= '0';
101)             r_ram_wr_addr <= (OTHERS => '0');
102)             r_ram_wr_data <= (OTHERS => '0');
103)             r_ram_wr_en   <= '0';
104)         ELSIF rising_edge(clk) THEN
105)             -- read
106)             IF i_rd_en = '1' AND s_rd_rdy = '1' THEN
107)                 r_begin      <= next_pos(r_begin);
108)                 r_begin_chgd <= '1';
109)             ELSE
110)                 r_begin_chgd <= '0';
111)             END IF;
112)             -- write
113)             IF i_wr_en = '1' AND s_wr_rdy = '1' THEN
114)                 r_ram_wr_addr <= std_logic_vector(to_unsigned(r_end, addr_width));
115)                 r_ram_wr_data <= i_wr_data;
116)                 r_ram_wr_en   <= '1';
Stefan Schuermans fixed FIFO implementation

Stefan Schuermans authored 12 years ago

117)                 r_end         <= next_pos(r_end);
Stefan Schuermans added FIFO to UART TX

Stefan Schuermans authored 12 years ago

118)             ELSE
119)                 r_ram_wr_en  <= '0';
120)             END IF;
121)             -- delay r_end 2 cycles: 1 for writing to RAM, 1 to read RAM
Stefan Schuermans fixed FIFO implementation

Stefan Schuermans authored 12 years ago

122)             r_end_dly1 <= r_end;
123)             r_end_dly2 <= r_end_dly1;