type type_variable_size_word is
record
one_byte_word : std_logic_vector ( 1 * 8 - 1 downto 0 ) ;
two_byte_word : std_logic_vector ( 2 * 8 - 1 downto 0 ) ;
three_byte_word : std_logic_vector ( 3 * 8 - 1 downto 0 ) ;
four_byte_word : std_logic_vector ( 4 * 8 - 1 downto 0 ) ;
end record ;
signal variable_size_word : type_variable_size_word ;
signal a : std_logic_vector ( 1 * 8 - 1 downto 0 ) ;
signal b : std_logic_vector ( 2 * 8 - 1 downto 0 ) ;
signal c : std_logic_vector ( 3 * 8 - 1 downto 0 ) ;
signal d : std_logic_vector ( 4 * 8 - 1 downto 0 ) ;
What is the syntax to assign a , b , c and d accordingly to my record signal ?
signal variable_size_word: type_variable_size_word;
-- One way
variable_size_word.one_byte_word <= a;
variable_size_word.two_byte_word <= b;
variable_size_word.three_byte_word <= c;
variable_size_word.four_byte_word <= d;
-- Another way
variable_size_word <=
(
one_byte_word => a,
two_byte_word => b,
three_byte_word => c,
four_byte_word => d
);
one_byte_word : std_logic_vector ( 1 * 8 - 1 downto 0 ) ;
two_byte_word : std_logic_vector ( 2 * 8 - 1 downto 0 ) ;
.
.
.
hundred_byte_word : std_logic_vector ( 100 * 8 - 1 downto 0 ) ;
No, not with record elements. However, if you only need only one of the elements and you just don't know ahead of time which one that would be, then you could use a generate loop but there you would define the vector size as a function of the generate index.Is there some way to do the assignments in an iterative fashion (like a generate loop) ?
type type_variable_size_word is
record
iterative_record_declaration : for index in 1 to 100
generate
x_byte_word : std_logic_vector ( index * 8 - 1 downto 0 ) ;
end generate ;
end record ;
You're right, it is not valid but it's not clear to me just what abstraction you're trying to get at anyway, you'll need to clarify. Some questions that will help:And what about iterative record declaration?
Something like:
I'm sure the above isn't valid - but is there any VHDL mechanism that can enable such abstraction ?Code:type type_variable_size_word is record iterative_record_declaration : for index in 1 to 100 generate x_byte_word : std_logic_vector ( index * 8 - 1 downto 0 ) ; end generate ; end record ;
Ex1 : for index in 1 to 100 generate
signal x_byte_word : std_logic_vector ( index * 8 - 1 downto 0 ) ;
begin
....
-- Here you can access only the 'x_byte_word' that corresponds with the single value
-- of 'index'. There would be no visibility to the 'x_byte_word' that goes along with any
-- other value of index.
end generate Ex1;
type t_Ex2 is record
Value: integer; -- Will limit you though to the size of a VHDL integer, 31 bits
Sizeof: positive;
end record t_Ex2;
type arr_t_Ex2 is array(natural range<>) of t_Ex2;
signal My_Sig: arr_t_Ex2(1 to 100);
-- Now you have complete access to any of the 100 values. They can be cast into
-- std_logic_vectors like this...
some_slv <= std_logic_vector(to_unsigned(My_Sig(i).Value, My_Sig(i).Sizeof));
Because I'm using the incoming 128 bit chunks to assemble a much bigger message of 12,800 bits.Why are you slicing the data bus?
Still sounds like you want register enables. The 128 data bits go to all 100 sets. You enable bits 127 downto 0 when empty is 0, 239 downto 128 when empty is 1, etc. Each bank of 128 clocks in the data only when its particular enable bit is set to 1 in which case it clocks in all 128 bits. There is no need to do anything with the data. Just create a 100 bit vector of register enable signals and bring the 128 data bits into all 100 destinations of the bigger message register.Because I'm using the incoming 128 bit chunks to assemble a much bigger message of 12,800 bits.
For example:
First cycle:
empty is 0
So we take data bits 127 downto 0 and drive it to bits 127 downto 0 of the bigger message register.
Second cycle:
empty is 2
So we take data bits 111 downto 0 and drive it to bits 239 downto 128 of the bigger message register.
And so on...
number_of_valid_symbols <= number_of_symbols - empty ;
generate_enable_vector : for index in 1 to number_of_symbols
generate
if number_of_valid_symbols >= index then
enable_vector ( index ) <= '1' ;
else
enable_vector ( index ) <= '0' ;
end if ;
end generate generate_enable_vector ;
record DataBus is
data : std_logic_vector;
en : std_logic;
end record;
This line looks questionable...
if number_of_valid_symbols >= index then
Since it will select multiple bits of 'enable_vector' and set them to '1'. Maybe that's what you want, I dunno. I would've expected an = not >=
number_of_valid_symbols <= number_of_symbols - empty ;
process ( clock ) is
begin
if rising_edge ( clock ) then
if valid = '1' then
whole_message ( ( pointer + number_of_valid_symbols * symbol_size - 1 ) downto pointer <= incoming_message ( number_of_valid_symbols * symbol_size - 1 downto 0 ) ;
pointer <= pointer + number_of_valid_symbols * symbol_size ;
end if ;
end if ;
end process ;
I know it would...The logic for this I forsee being rather hiddeous
Because the whole message will have to be parsed in parallel after I'm done filling it.Why do you need to remove the invalid words?
I'm getting the Avalon Stream from an third party IP - and this is how it works.Why are you using empty on a per word basis?
The only way I can visualize it is with pre-slicing the data bus to all the possible vector sizes...Please think about how you would draw this circuit (because you did document the design before you wrote the code right?)
The only way I can visualize it is with pre-slicing the data bus to all the possible vector sizes...
No. The application is entirely embedded in the FPGA - no software involvement.Im assuming you're buffering the word for a PC
current_valid_symbols <= total_symbols - empty ;
process ( clock ) is
begin
if rising_edge ( clock ) then
if valid = '1' and current_valid_symbols > 1 then
big_message ( ( pointer + current_valid_symbols * 8 - 1 ) downto pointer ) <= message ( current_valid_symbols * 8 - 1 downto 0 ) ;
pointer <= pointer + current_valid_symbols * 8 ;
end if ;
end if ;
end process ;
Kevin,
Perhaps I didn't explain it properly.
Incoming data is 128 bits ( 8 bits per symbol = 16 symbols ).
Example:
First cycle:
empty is 15 ( only one valid symbol )
So we take data bits 7 downto 0 and drive it to bits 7 downto 0 of the bigger message register.
Second cycle:
empty is 14 ( only two valid symbols )
So we take data bits 15 downto 0 and drive it to bits 23 downto 8 of the bigger message register.
We do so, because the previous cycle filled only bits (7 downto 0). In other words - I want to discard the empty message section and "squeeze" the new valid data to the exact place where the last transaction finished.
Only when empty = 128 (KJ: Did you mean 0 here?) our pointer makes a full 128 bit increment.
Something in this spirit...only synthesizable:
Can you post an example that does that?Code:number_of_valid_symbols <= number_of_symbols - empty ; process ( clock ) is begin if rising_edge ( clock ) then if valid = '1' then whole_message ( ( pointer + number_of_valid_symbols * symbol_size - 1 ) downto pointer <= incoming_message ( number_of_valid_symbols * symbol_size - 1 downto 0 ) ; pointer <= pointer + number_of_valid_symbols * symbol_size ; end if ; end if ; end process ;
constant MAX_SYMBOLS: natural := 16;
signal Next_Symbol: natural range 0 to (MAX_SYMBOLS-1); -- The range of symbols
signal empty: natural range 0 to (MAX_SYMBOLS-1); -- From Avalon
constant BITS_PER_SYMBOL: natural := 8;
signal Data_In: std_ulogic_vector((BITS_PER_SYMBOL-1) downto 0); -- From Avalon
constant MSGS_PER_BIG_MSG: natural := 100; -- What you had stated
signal My_Big_Msg: std_ulogic_vector(BITS_PER_SYMBOL*MAX_SYMBOLS*MSGS_PER_BIG_MSG-1 downto 0);
...
process(clock)
begin
if rising_edge(clock) then
if (Some_Form_Of_Reset = '1') then
Next_Symbol <= 0;
elsif (valid = '1') then
[COLOR=#ff0000]if (TBD) then -- How to handle wrapping needs to be decided[/COLOR]
Next_Symbol <= 0;
else
Next_Symbol <= Next_Symbol + MAX_SYMBOLS-1-empty;
end if;
end if;
for i in 0 to (MSGS_PER_BIG_MSG-1) loop
if (Next_Symbol >= i) then -- KJ: Essentially creates the enable signal here
for i in Data_In'range loop
My_Big_Message(BITS_PER_SYMBOL * i) <= Data_In(i);
end loop;
end if;
end loop;
end if;
end process;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?