G
glenn.christian@gmail.com
Guest
Hi,
I am trying to find a way in VHDL of assigning arbitrary length signals to a bus, and programmatically assigning the bus indices for these signals. A very simple example is given below, where I am manually assigning the three differing length signals to one bus:
*****************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity bus_top is
port (
bus_out : out std_logic_vector(5 downto 0)
);
end bus_top;
architecture rtl of bus_top is
signal b : std_logic_vector(2 downto 0) := "101";
signal c : std_logic_vector(1 downto 0) := "11";
signal d : std_logic_vector(0 downto 0) := "0";
begin
-- Bus assembly ----
bus_out(0) <= b(0);
bus_out(1) <= b(1);
bus_out(2) <= b(2);
bus_out(3) <= c(0);
bus_out(4) <= c(1);
bus_out(5) <= d(0);
end rtl;
****************************************************************
This simulates and synthesises as expected, to a constantly driven "011101" output. Of course my real application is much more complicated than this, and involves assembling many more signals, of differing lengths, on to the bus, and I do not want to have to manually change all the indices, when the size of one of the signals changes. I would like to find a way to automatically provide the bus indices using, for example, the signal's 'length attributes, in a similar way to the following:
****************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity bus_top is
port (
bus_out : out std_logic_vector(5 downto 0)
);
end bus_top;
architecture rtl of bus_top is
signal b : std_logic_vector(2 downto 0) := "101";
signal c : std_logic_vector(1 downto 0) := "11";
signal d : std_logic_vector(0 downto 0) := "0";
begin
-- Bus assembly ----
bus_assemble: process (b,c,d)
variable bus_ind : integer := 0;
begin
bus_out <= (others => '0'); -- avoids latch inference
bus_out(bus_ind+b'length-1 downto bus_ind) <= b;
bus_ind := bus_ind + b'length;
bus_out(bus_ind+c'length-1 downto bus_ind) <= c;
bus_ind := bus_ind + c'length;
bus_out(bus_ind+d'length-1 downto bus_ind) <= d;
end process;
end rtl;
****************************************************************
Note the above code is not the correct solution as, although it appears to simulate correctly, the logic being sythesised is far more complex with many LUTs being inferred for what is just a static assignment. I feel it must be possible in VHDL to do this such that the synthesis tool will 'unroll' the statements in the same way as in the first example, eg for the indices to be calculated by the tools at compile-time rather than on the FPGA at run-time. This would require that the signals are assigned sequentially, and some way to keep track of the previous value of the bus index, but I have not been able to find the right construct for this: I have looked at processes (as above), regular loops, generate loops, functions and procedures. Can anyone shed some light on how to do this? I am aware there are other ways to achieve similar results, such as simple concatenation, or using a higher level programming language to automatically generate/annotate the VHDL, but I would like to understand how to do this in the manner above.
Many thanks for your help,
Glenn.
I am trying to find a way in VHDL of assigning arbitrary length signals to a bus, and programmatically assigning the bus indices for these signals. A very simple example is given below, where I am manually assigning the three differing length signals to one bus:
*****************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity bus_top is
port (
bus_out : out std_logic_vector(5 downto 0)
);
end bus_top;
architecture rtl of bus_top is
signal b : std_logic_vector(2 downto 0) := "101";
signal c : std_logic_vector(1 downto 0) := "11";
signal d : std_logic_vector(0 downto 0) := "0";
begin
-- Bus assembly ----
bus_out(0) <= b(0);
bus_out(1) <= b(1);
bus_out(2) <= b(2);
bus_out(3) <= c(0);
bus_out(4) <= c(1);
bus_out(5) <= d(0);
end rtl;
****************************************************************
This simulates and synthesises as expected, to a constantly driven "011101" output. Of course my real application is much more complicated than this, and involves assembling many more signals, of differing lengths, on to the bus, and I do not want to have to manually change all the indices, when the size of one of the signals changes. I would like to find a way to automatically provide the bus indices using, for example, the signal's 'length attributes, in a similar way to the following:
****************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity bus_top is
port (
bus_out : out std_logic_vector(5 downto 0)
);
end bus_top;
architecture rtl of bus_top is
signal b : std_logic_vector(2 downto 0) := "101";
signal c : std_logic_vector(1 downto 0) := "11";
signal d : std_logic_vector(0 downto 0) := "0";
begin
-- Bus assembly ----
bus_assemble: process (b,c,d)
variable bus_ind : integer := 0;
begin
bus_out <= (others => '0'); -- avoids latch inference
bus_out(bus_ind+b'length-1 downto bus_ind) <= b;
bus_ind := bus_ind + b'length;
bus_out(bus_ind+c'length-1 downto bus_ind) <= c;
bus_ind := bus_ind + c'length;
bus_out(bus_ind+d'length-1 downto bus_ind) <= d;
end process;
end rtl;
****************************************************************
Note the above code is not the correct solution as, although it appears to simulate correctly, the logic being sythesised is far more complex with many LUTs being inferred for what is just a static assignment. I feel it must be possible in VHDL to do this such that the synthesis tool will 'unroll' the statements in the same way as in the first example, eg for the indices to be calculated by the tools at compile-time rather than on the FPGA at run-time. This would require that the signals are assigned sequentially, and some way to keep track of the previous value of the bus index, but I have not been able to find the right construct for this: I have looked at processes (as above), regular loops, generate loops, functions and procedures. Can anyone shed some light on how to do this? I am aware there are other ways to achieve similar results, such as simple concatenation, or using a higher level programming language to automatically generate/annotate the VHDL, but I would like to understand how to do this in the manner above.
Many thanks for your help,
Glenn.