library IEEE; use IEEE.std_logic_1164.all; library vfp; library FF; library multiplexer; architecture modular of reg_file_32_8_6port is use vfp.integer_class.all; use FF.d_latch_cmpt.all; use multiplexer.demux_gen_cmpt.all; use multiplexer.mux_gen_cmpt.all; constant depth : integer := 32; constant data_width : integer := 8; constant num_input_ports : integer := num_write_ports + num_bidirectional_ports; constant num_output_ports : integer := num_read_ports + num_bidirectional_ports; type select_bus is array (0 to num_input_ports-1) of std_ulogic_vector(depth-1 downto 0); -- 3 busses, 32 bits wide type address_write_bus is array (0 to num_input_ports-1) of std_ulogic_vector(log_2(depth)-1 downto 0); type address_read_bus is array (0 to num_output_ports-1) of std_ulogic_vector(log_2(depth)-1 downto 0); type data_write_bus is array (0 to num_input_ports-1) of std_ulogic_vector(data_width-1 downto 0); type data_read_bus is array (0 to num_output_ports-1) of std_ulogic_vector(data_width-1 downto 0); signal data_WR_select : select_bus; signal addr_WR : address_write_bus; signal addr_RD : address_read_bus; signal WE_WR : std_ulogic_vector(0 to num_input_ports-1); signal OE_RD : std_ulogic_vector(0 to num_output_ports-1); signal data_WR : data_write_bus; signal latch_array_in : std_ulogic_2D_array(0 to depth-1, data_width-1 downto 0); signal latch_array_out : std_ulogic_2D_array(0 to depth-1, data_width-1 downto 0); signal mux_out : data_read_bus; signal en : std_ulogic_vector(0 to depth-1); begin s2: WE_WR <= not write; s3: OE_RD <= read; g3: for i in 0 to num_input_ports-1 generate g4: for j in 0 to log_2(depth)-1 generate addr_WR(i)(j) <= address_write(i, j); end generate g4; decode_addr_WR: demux_generic generic map ( in_width => log_2(depth) ) port map ( a => addr_WR(i), enable => WE_WR(i), y => data_WR_select(i) ); end generate g3; g5: for i in data_in'RANGE(1) generate g6: for j in 0 to data_width-1 generate data_WR(i)(j) <= data_in(i, j); end generate g6; end generate g5; data_mux_selects: process (data_WR, data_WR_select) variable enable : std_ulogic_vector(0 to depth-1); begin for k in 0 to depth-1 loop for i in 0 to data_width-1 loop latch_array_in(k,i) <= data_WR(0)(i); end loop; enable(k) := '0'; for j in 0 to num_input_ports-1 loop enable(k) := data_WR_select(j)(k) or enable(k); end loop; en(k) <= not enable(k); for j in 0 to num_input_ports-1 loop if data_WR_select(j)(k) = '1' then for i in 0 to data_width-1 loop latch_array_in(k,i) <= data_WR(j)(i); end loop; end if; end loop; end loop; end process; g0: for i in 0 to depth-1 generate g1: for j in 0 to data_width-1 generate latch_instance: d_latch port map ( d => latch_array_in(i,j), enable => en(i), q => latch_array_out(i,j) ); end generate g1; end generate g0; g2: for i in 0 to num_output_ports-1 generate g8: for j in address_read'RANGE(0) generate addr_RD(i)(j) <= address_read(i, j); end generate g8; op_mux: mux_generic generic map ( data_width => data_width, funnel_factor => depth ) port map ( a => latch_array_out, sel => addr_RD(i), y => mux_out(i) ); end generate g2; gi_mux: for i in 0 to num_output_ports-1 generate gj_data: for j in 0 to data_width-1 generate data_out(i,j) <= mux_out(i)(j); end generate gj_data; end generate gi_mux; end modular;