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 |