Model of the Month |
We can
update you automatically when this page changes. To receive regular notification of updates to our Model of the Month section, click here. |
6-port Register FileThis month, we present a 6-port Register File model. The logical function of a register file is very simple, it is after all the identity function, but once you start adding multiple read and write ports, the complexity of modeling such a device seems to grow at an alarming rate. This register file has 3 wite and 3 read ports. I was planning to add a bidirectional port capability too, but figured this could wait until I developed a fully parameterizable register file model (just dont hold your breath!). So this model has a depth of 32 registers, each register being 8 bits wide. When it comes to coding up the design, there are a couple of key choices to make behavioural or structural coding style. I trod the structural path this month, as this allowed me to play with a variety of VHDL coding techniques. It also seemed that a behavioural approach wouldnt be as challenging... From the code, you can see that quite a few generate statements are used. Sometimes the generate loop uses an array attribute, sometimes it uses a constant for the loop parameter. Many of the internal signals required the definition of their own data type. This was a synthesis tool constraint rather than a modeling decision, but thats another story. I also decided to mix multi-dimensional array indexing approaches. The register file ports and the latch actual signals are 2-index arrays whereas most of the other signals are arrays of vectors. To implement the register file in a reasonably efficient way, I opted to use latches as the storage elements rather than flip-flops. There is no write address port conflict arbitration as yet. You are welcome to use the source code we provide but you must keep the copyright notice with the code (see the Acknowledgements page for more details). The VFP Library is required for simulating this
month's Model of the Month. -- register_file_32_8_6port -- -- +-----------------------------+ -- | Copyright 1998 DOULOS | -- | Library: register_file | -- | designer : Tim Pagden | -- | opened: 11 Jul 1998 | -- +-----------------------------+ library IEEE; library vfp; use IEEE.std_logic_1164.all; use vfp.hardware_specifications.all; entity reg_file_32_8_6port is generic ( num_write_ports : integer := 1; num_read_ports : integer := 1; num_bidirectional_ports : integer := 0 ); port ( write : in std_ulogic_vector(((num_write_ports-1) + num_bidirectional_ports) downto 0); read : in std_ulogic_vector((( num_read_ports-1) + num_bidirectional_ports) downto 0); address_write : in std_ulogic_2D_array(0 to 2, 4 downto 0); address_read : in std_ulogic_2D_array(0 to 2, 4 downto 0); data_in : in std_ulogic_2D_array(0 to 2, 7 downto 0); data_out : out std_ulogic_2D_array(0 to 2, 7 downto 0) ); end reg_file_32_8_6port; -- Architectures: -- 11.07.98 behaviour 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); 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; To download the VHDL source code for
this month's
|
FPGA
/ ASIC Design and Project Services
Doulos Training Courses
Copyright 1995-1998 Doulos
This page was last updated 4th July 1998.
We welcome your e-mail comments. Please contact us at: webmaster@doulos.co.uk