Stefan Schuermans commited on 2012-03-11 18:59:11
Showing 1 changed files, with 54 additions and 50 deletions.
... | ... |
@@ -36,22 +36,24 @@ ARCHITECTURE a_block_fifo OF e_block_fifo IS |
36 | 36 |
); |
37 | 37 |
END COMPONENT e_block_rwram; |
38 | 38 |
|
39 |
- SUBTYPE t_addr_n IS natural RANGE 0 TO 2 ** addr_width - 1; |
|
39 |
+ SUBTYPE t_pos IS natural RANGE 0 TO 2 ** addr_width - 1; |
|
40 | 40 |
SUBTYPE t_addr IS std_logic_vector(addr_width - 1 DOWNTO 0); |
41 | 41 |
SUBTYPE t_data IS std_logic_vector(data_width - 1 DOWNTO 0); |
42 | 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; |
|
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 |
|
53 | 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 |
|
54 | 55 |
SIGNAL s_wr_rdy: std_logic; |
56 |
+ SIGNAL s_wr_en: std_logic; |
|
55 | 57 |
|
56 | 58 |
FUNCTION next_pos ( |
57 | 59 |
pos: natural RANGE 0 TO 2 ** addr_width - 1 |
... | ... |
@@ -66,15 +68,14 @@ ARCHITECTURE a_block_fifo OF e_block_fifo IS |
66 | 68 |
RETURN v_next; |
67 | 69 |
END FUNCTION next_pos; |
68 | 70 |
|
71 |
+ FUNCTION to_addr ( |
|
72 |
+ pos: natural RANGE 0 TO 2 ** addr_width - 1 |
|
73 |
+ ) RETURN std_logic_vector IS |
|
69 | 74 |
BEGIN |
75 |
+ RETURN std_logic_vector(to_unsigned(pos, addr_width)); |
|
76 |
+ END FUNCTION to_addr; |
|
70 | 77 |
|
71 |
- s_ram_rd_addr <= std_logic_vector(to_unsigned(r_begin, addr_width)); |
|
72 |
- |
|
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'; |
|
75 |
- |
|
76 |
- o_rd_rdy <= s_rd_rdy; |
|
77 |
- o_wr_rdy <= s_wr_rdy; |
|
78 |
+BEGIN |
|
78 | 79 |
|
79 | 80 |
i_rwram: e_block_rwram |
80 | 81 |
GENERIC MAP ( |
... | ... |
@@ -83,46 +84,49 @@ BEGIN |
83 | 84 |
) |
84 | 85 |
PORT MAP ( |
85 | 86 |
clk => clk, |
86 |
- i_rd_addr => s_ram_rd_addr, |
|
87 |
+ i_rd_addr => s_begin_sn_addr, |
|
87 | 88 |
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 |
|
89 |
+ i_wr_addr => s_end_addr, |
|
90 |
+ i_wr_data => i_wr_data, |
|
91 |
+ i_wr_en => s_wr_en |
|
91 | 92 |
); |
92 | 93 |
|
93 |
- p_fifo: PROCESS(rst, clk) |
|
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) |
|
94 | 120 |
BEGIN |
95 | 121 |
IF rst = '1' THEN |
96 | 122 |
r_begin <= 0; |
97 | 123 |
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'; |
|
124 |
+ r_end_addr_delay <= (OTHERS => '0'); |
|
104 | 125 |
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'; |
|
117 |
- r_end <= next_pos(r_end); |
|
118 |
- ELSE |
|
119 |
- r_ram_wr_en <= '0'; |
|
126 |
+ r_begin <= n_begin; |
|
127 |
+ r_end <= n_end; |
|
128 |
+ r_end_addr_delay <= s_end_addr; |
|
120 | 129 |
END IF; |
121 |
- -- delay r_end 2 cycles: 1 for writing to RAM, 1 to read RAM |
|
122 |
- r_end_dly1 <= r_end; |
|
123 |
- r_end_dly2 <= r_end_dly1; |
|
124 |
- END IF; |
|
125 |
- END PROCESS p_fifo; |
|
130 |
+ END PROCESS p_sync; |
|
126 | 131 |
|
127 | 132 |
END ARCHITECTURE a_block_fifo; |
128 |
- |
|
129 | 133 |