Filling chunks of vector

A

ALuPin@web.de

Guest
Hi Newsgroup,

defining the following vector

SIGNAL ls_data : std_logic_vector(63 DOWNTO 0);

I want to write chunks of 2 bit in that vector, that is

1.write
ls_data(1 DOWNTO 0) <= "11";

2.write
ls_data(3 DOWNTO 2) <= "11";
....
32. write
ls_data(63 DOWNTO 62) <= "11";


PROCESS(Reset, Clk)
BEGIN
IF Reset='1' THEN
ls_cnt <= 1;
ls_data <= (OTHERS => '0'):
ELSIF rising_edge(Clk) THEN
IF Write='1' THEN
IF ls_cnt=32 THEN
ls_cnt <= 1;
ELSE
ls_cnt <= ls_cnt + 1;
END IF;


FOR i IN 1 TO 32 LOOP
IF (i=2*ls_cnt - 1) OR (i=2*ls_cnt -2) THEN
ls_data(i) <= '1';
END IF;
END LOOP;

END IF;
END IF;
END PROCESS;

Is there a more elegant way to fill the chunks in the vector ?

Rgds
André
 
ALuPin@web.de wrote:

Is there a more elegant way to fill the chunks in the vector ?
I would declare a 64 bit constant mask vector
and OR that with the value of ls_data.

-- Mike Treseler
 
I'm assuming this is supposed to be synthesizable?

Within your for loop, the index becomes "static" when synthesis unrolls
the loop, so I would do any arithmetic on "i" and not on "ls_cnt",
since that arithmetic would get done at compile time, not in hardware:

if (i + 1) / 2 = ls_cnt) or ((i + 2) / 2 = ls_cnt then

However, you can get rid of the entire loop by indexing directly with
ls_cnt:

ls_data(2 * ls_cnt - 1) <= '1';
ls_data(2 * ls_cnt - 2) <= '1';

or even:

ndx := 2 * ls_cnt - 1;
ls_data(ndx downto ndx - 1) <= "11";

BTW, ls_cnt will be more efficient if it counts from 0 to 31, instead
of 1 to 32 (one less bit to count and decode)

Another question: in between writing di-bits to this vector, are the
remaining contents supposed to be unaffected? If not, you could simply
shift in two ones at a time:

ls_data <= ls_data(61 downto 0) & "11";

Even if not, it would probably be more efficient to create a johnson
counter that circularly shifts two ones around a 64 bit ring, and OR
that with ls_data, rather than creating a binary counter and decoding
the count to the indices you have to update.

I also assume that at some point (count), you should be reloading
ls_data with some input pattern? Or is this thing supposed to simply
reset to all zeroes, and then fill up with ones, and then just keep
filling?

Andy






ALuPin@web.de wrote:
Hi Newsgroup,

defining the following vector

SIGNAL ls_data : std_logic_vector(63 DOWNTO 0);

I want to write chunks of 2 bit in that vector, that is

1.write
ls_data(1 DOWNTO 0) <= "11";

2.write
ls_data(3 DOWNTO 2) <= "11";
...
32. write
ls_data(63 DOWNTO 62) <= "11";


PROCESS(Reset, Clk)
BEGIN
IF Reset='1' THEN
ls_cnt <= 1;
ls_data <= (OTHERS => '0'):
ELSIF rising_edge(Clk) THEN
IF Write='1' THEN
IF ls_cnt=32 THEN
ls_cnt <= 1;
ELSE
ls_cnt <= ls_cnt + 1;
END IF;


FOR i IN 1 TO 32 LOOP
IF (i=2*ls_cnt - 1) OR (i=2*ls_cnt -2) THEN
ls_data(i) <= '1';
END IF;
END LOOP;

END IF;
END IF;
END PROCESS;

Is there a more elegant way to fill the chunks in the vector ?

Rgds
André
 
Hello André,


You could define a type:
type t_ls_data is array 0 to 31 of std_logic_vector(1 downto 0);
signal ls_data : t_ls_data;
signal ls_data_slv : std_logic_vector(63 downto 0);

in the function you then write:
for i in 0 to 31 loop
ls_data(i) <= "11";
end loop;

or if they are all the same chunks of e.g. value "10", you can make it:
ls_data <= (others => "10");

when you need your vector back, define a function:
function ConvertToSlv(ls_data : t_ls_data) return
std_logic_vector(63 downto 0) is
variable Result : std_logic_vector(63 downto 0);
begin
for i in 0 to 31 loop
Result(2*i+1 downto 2*i) := ls_data(i);
end loop;
end function ConvertToSlv;

in your architecture you can then say:
ls_data_slv <= ConvertToSlv(ls_data);

All this is synthesizable, speedy and compact.



Best regards,
Robert.





ALuPin@web.de wrote:
Hi Newsgroup,

defining the following vector

SIGNAL ls_data : std_logic_vector(63 DOWNTO 0);

I want to write chunks of 2 bit in that vector, that is

1.write
ls_data(1 DOWNTO 0) <= "11";

2.write
ls_data(3 DOWNTO 2) <= "11";
...
32. write
ls_data(63 DOWNTO 62) <= "11";


PROCESS(Reset, Clk)
BEGIN
IF Reset='1' THEN
ls_cnt <= 1;
ls_data <= (OTHERS => '0'):
ELSIF rising_edge(Clk) THEN
IF Write='1' THEN
IF ls_cnt=32 THEN
ls_cnt <= 1;
ELSE
ls_cnt <= ls_cnt + 1;
END IF;


FOR i IN 1 TO 32 LOOP
IF (i=2*ls_cnt - 1) OR (i=2*ls_cnt -2) THEN
ls_data(i) <= '1';
END IF;
END LOOP;

END IF;
END IF;
END PROCESS;

Is there a more elegant way to fill the chunks in the vector ?

Rgds
André
 

Welcome to EDABoard.com

Sponsor

Back
Top