generate statements instructors: fu-chiung cheng ( 鄭福炯 ) associate professor computer science...
TRANSCRIPT
Generate Statements
Instructors: Fu-Chiung Cheng
(鄭福炯 )Associate Professor
Computer Science & EngineeringTatung University
Regular Structure
Many digital systems can be implemented as regular iterative compositions of subsystems – Memory: a rectangular array of storage cell– Adders, comparators: linear array or tree structure– Multipliers:
Generate statements in VHDL can be used to generate regular structures
Generating Iterative Structure
Iterative structure– Components: processes or component
instantiation– Repetition: Generate statement
EBNF: page 350 Example:
Fig 14.1library ieee; use ieee.std_logic_1164.all;entity register_tristate is generic ( width : positive ); port ( clock : in std_logic; out_enable : in std_logic; data_in : in std_logic_vector(0 to width - 1); data_out : out std_logic_vector(0 to width - 1) );end entity register_tristate;--------------------------------------------------architecture cell_level of register_tristate is component D_flipflop is port ( clk : in std_logic; d : in std_logic; q : out std_logic ); end component D_flipflop; component tristate_buffer is port ( a : in std_logic; en : in std_logic; y : out std_logic ); end component tristate_buffer;begin -- generate statementend architecture cell_level;
Fig 14.1cont.
library ieee; use ieee.std_logic_1164.all;entity register_tristate is generic ( width : positive ); port ( clock : in std_logic; out_enable : in std_logic; data_in : in std_logic_vector(0 to width - 1); data_out : out std_logic_vector(0 to width - 1) );end entity register_tristate;--------------------------------------------------architecture cell_level of register_tristate is
-- some declaration begin cell_array : for bit_index in 0 to width - 1 generate signal data_unbuffered : std_logic; begin cell_storage : component D_flipflop port map ( clk => clock, d => data_in(bit_index),
q => data_unbuffered ); cell_buffer : component tristate_buffer port map ( a => data_unbuffered, en => out_enable, y => data_out(bit_index) ); end generate cell_array;end architecture cell_level;
Example 14.2
Matrix Operation: see page 352 p(i)’ = a(i,1)*p(1)+ a(i,2)*p(2)+ a(i,3)*p(3) for
i=1,2,3 Make this output pipelined (may not be
necessary)
Fig 14.2architecture behavioral of graphics_engine is type point is array (1 to 3) of real; type transformation_matrix is array (1 to 3, 1 to 3) of real; signal p, transformed_p : point; signal a : transformation_matrix; signal clock : bit; -- . . .begin transform_stage : for i in 1 to 3 generate begin cross_product_transform : process is variable result1, result2, result3 : real := 0.0; begin wait until clock = '1'; transformed_p(i) <= result3; result3 := result2; result2 := result1; result1 := a(i, 1) * p(1) + a(i, 2) * p(2) + a(i, 3) * p(3); end process cross_product_transform; end generate transform_stage; -- …end architecture behavioral;
Two Dimensional Structure
Nested generate statement can be used to construct multi-dimensional structure
Nesting of generate statements is allowed in VHDL since a generate statement is a kind of concurrent statements
Outer statement creates the row of the structure and the inner statement creates the elements within each row
Fig 14.3architecture chip_level of memory_board is component DRAM is port ( a : in std_logic_vector(0 to 10); d : inout std_logic_vector(0 to 3); cs, we, ras, cas : in std_logic ); end component DRAM; signal buffered_address : std_logic_vector(0 to 10); signal DRAM_data : std_logic_vector(0 to 31); signal bank_select : std_logic_vector(0 to 3); signal buffered_we, buffered_ras, buffered_cas : std_logic; -- . . . -- other declarationsbegin bank_array : for bank_index in 0 to 3 generate begin nibble_array : for nibble_index in 0 to 7 generate constant data_lo : natural := nibble_index * 4; constant data_hi : natural := nibble_index * 4 + 3; begin a_DRAM : component DRAM port map ( a => buffered_address, d => DRAM_data(data_lo to data_hi), cs => bank_select(bank_index), we => buffered_we, ras => buffered_ras, cas => buffered_cas ); end generate nibble_array; end generate bank_array; -- . . . -- other component instances, etcend architecture chip_level;
Conditionally Generating Structures
Each cell in an iterative structure may not be connected identically.
In some design some particular cells may be treated differently– Boundary cells
Conditional generate statement can be used to deal with these special cases within an iterative structure
EBNF: page 355 Example:
Fig 14.5library ieee; use ieee.std_logic_1164.all;entity shift_reg is -- serial to parallel shift register port ( phi1, phi2 : in std_logic; serial_data_in : in std_logic; parallel_data : inout std_logic_vector );end entity shift_reg;--------------------------------------------------architecture cell_level of shift_reg is alias normalized_parallel_data : std_logic_vector(0 to parallel_data'length - 1) is parallel_data;
component master_slave_flipflop is port ( phi1, phi2 : in std_logic; d : in std_logic; q : out std_logic ); end component master_slave_flipflop;
begin -- statementsend architecture cell_level;
Fig 14.5cont.
architecture cell_level of shift_reg is-- declaration
begin reg_array : for index in normalized_parallel_data'range generate begin first_cell : if index = 0 generate begin cell : component master_slave_flipflop port map ( phi1, phi2, d => serial_data_in, q => normalized_parallel_data(index) ); end generate first_cell;
other_cell : if index /= 0 generate begin cell : component master_slave_flipflop port map ( phi1, phi2, d => normalized_parallel_data(index - 1), q => normalized_parallel_data(index) ); end generate other_cell; end generate reg_array;end architecture cell_level;
Fig 14.6entity computer_system is generic ( instrumented : boolean := false ); port ( -- . . . );end entity computer_system;---------------------------------------------------------------------------------architecture block_level of computer_system is . . . -- type and component declarations for cpu and memory, etc signal clock : bit; -- the system clock signal mem_req : bit; -- cpu access request to memory signal ifetch : bit; -- indicates access is to fetch an instruction signal write : bit; -- indicates access is a write -- . . . -- other signal declarationsbegin -- . . . -- component instances for cpu and memory, etc instrumentation : if instrumented generate signal ifetch_freq, write_freq, read_freq : real := 0.0; begin
-- …. Put code here end generate instrumentation;end architecture block_level;
Fig 14.6 for system_under_test : computer_system use entity work.computer_system(block_level) generic map ( instrumented => true ) -- . . . -- not in book ; -- end not in book end for;
Recursive Structures
A more useful application of conditional generate statements arises when describing recursive hardware structure such as tree structures
Example: Clock tree in – Fig 14.7– Check the recursive part– Implementation in Fig 14.8
Fig 14.8library ieee; use ieee.std_logic_1164.all;entity fanout_tree is generic ( height : natural ); port ( input : in std_logic; output : out std_logic_vector (0 to 2**height - 1)
);end entity fanout_tree;--------------------------------------------------architecture recursive of fanout_tree isbegin
-- recursive component instantiationend architecture recursive;
Fig 14.8architecture recursive of fanout_tree isbegin degenerate_tree : if height = 0 generate begin output(0) <= input; end generate degenerate_tree; compound_tree : if height > 0 generate signal buffered_input_0, buffered_input_1 : std_logic; begin buf_0 : entity work.buf(basic) port map ( a => input, y => buffered_input_0 ); subtree_0 : entity work.fanout_tree(recursive) generic map ( height => height - 1 ) port map ( input => buffered_input_0, output => output(0 to 2**(height - 1) - 1) ); buf_1 : entity work.buf(basic) port map ( a => input, y => buffered_input_1 ); subtree_1 : entity work.fanout_tree(recursive) generic map ( height => height - 1 ) port map ( input => buffered_input_1, output => output(2**(height - 1) to 2**height - 1) ); end generate compound_tree;end architecture recursive;
Fig 14.8
clock_buffer_tree : entity work.fanout_tree(recursive) generic map ( height => 3 ) port map ( input => unbuffered_clock, output => buffered_clock_array );
Configuration of Generate Statements
Block configuration can be used to choose which implementation to be used
EBNF: see page 362 Example:
Fig 14.9architecture block_level of computer_system is -- . . . -- type and component declarations for cpu and mem
ory, etc. signal clock : bit; -- the system clock signal mem_req : bit; -- cpu access request to memory signal ifetch : bit; -- indicates access is to fetch an instructi
on signal write : bit; -- indicates access is a write -- . . . -- other signal declarationsbegin -- . . . -- component instances for cpu and memory, etc. instrumentation : if instrumented generate use work.bus_monitor_pkg; signal bus_stats : bus_monitor_pkg.stats_type; begin cpu_bus_monitor : component bus_monitor_pkg.bus_moni
tor port map ( mem_req, ifetch, write, bus_stats ); end generate instrumentation;
Fig 14.10configuration architectural of computer_system is for block_level -- . . . -- component configurations for cpu and memory,
etc for instrumentation for cpu_bus_monitor : bus_monitor_pkg.bus_monitor use entity work.bus_monitor(general_purpose) generic map ( verbose => true, dump_stats => true ); end for; end for; -- intrumentation end for; -- block_level
end configuration architectural;
Fig 14.11-- For the register’ FlipFlop and tri-state buffer in -- Fig 14.1 we can configure the components-- by using configuration blocklibrary cell_lib;configuration identical_cells of register_tristate is for cell_level for cell_array for cell_storage : D_flipflop use entity cell_lib.D_flipflop(synthesized); end for; for cell_buffer : tristate_buffer use entity cell_lib.tristate_buffer(synthesized); end for; end for; end for;end configuration identical_cells;