Generic shift register where value 'n' keeps changing

M

methi

Hi,

I am working on the vhdl code of a generic shift register...

My code is as follows:

entity shifting is
generic ( left : integer );
Port ( shift_in : in std_logic;
clk_input : in std_logic;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is

signal shift_register : std_logic_vector ( (left-1) downto 0 ):=
(others => '0');

begin


process(clk_input)
begin
if rising_edge(clk_input) then
shift_register <= shift_register( (left-2) downto 0 ) & shift_in;
shift_out <= shift_register(left-1);
end if;
end process;



end Behavioral;


I am using this component in the top level code.

While doing generic map and port map of this components instantiation,

I dont want to assign a fixed value to "left".

I need my "left" changing every time another signal "h" changes


I tried doing this in the generic map:

generic map ( left => h)

But this gives me an error.

"h" is an integer.( have declared it as an integer in the top level
code).

Any ideas about how I can do this?


Thank you,

Methi
 
R

Ralf Hildebrandt

methi said:
entity shifting is
generic ( left : integer );
Port ( shift_in : in std_logic;
clk_input : in std_logic;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is

signal shift_register : std_logic_vector ( (left-1) downto 0 ):=
(others => '0');

begin


process(clk_input)
begin
if rising_edge(clk_input) then
shift_register <= shift_register( (left-2) downto 0 ) & shift_in;
shift_out <= shift_register(left-1);
end if;
end process;

end Behavioral;
While doing generic map and port map of this components instantiation,
I dont want to assign a fixed value to "left".
I need my "left" changing every time another signal "h" changes

What hardware may provide a 3-bit shift register as well as a 3000-bit
shift register? A 3000-bit shift register I guess... ;-)

I tried doing this in the generic map:

generic map ( left => h)

But this gives me an error.

Shure, because generic parameters have to be fixed at compile time.


Any ideas about how I can do this?

Model a shift register wide enough for your worst case. (Note, that then
everytime all these filpflops will be included.)

Additionally model a multiplexer, that selects the shift_out bit out of
these flipflops. The multiplexer has to be controlled by an input signal
(similar to your "left" parameter).


Ralf
 
M

methi

Ralf said:
What hardware may provide a 3-bit shift register as well as a 3000-bit
shift register? A 3000-bit shift register I guess... ;-)



Shure, because generic parameters have to be fixed at compile time.




Model a shift register wide enough for your worst case. (Note, that then
everytime all these filpflops will be included.)

Additionally model a multiplexer, that selects the shift_out bit out of
these flipflops. The multiplexer has to be controlled by an input signal
(similar to your "left" parameter).


Ralf


Hi Ralf,

Could I try this instead of using generics:

Use left as an input signal....declare it as an integer

So my code would be :

entity shifting is

Port ( shift_in : in std_logic;
clk_input : in std_logic;
left : in integer;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is


signal shift_register : std_logic_vector ((left-1) downto 0 ):= (others
=> '0');

begin


process(clk_input)
begin
if rising_edge(clk_input) then
shift_register <= shift_register( (left-2) downto 0 ) & shift_in;
shift_out <= shift_register(left-1);
end if;
end process;



end Behavioral;


I am not able to synthesize this because:

signal shift_register : std_logic_vector ((left-1) downto 0 ):= (others
=> '0');

This signal delcaration is giving me a synthesis error...It says that
left needs to be a constant instead...

Any other method to work around this idea?

Because I need the length of my shift register to change depending on
what i feed the FPGA through the front panel!


Thankyou ,

Methi
 
N

Nicolas Matringe

Could I try this instead of using generics:
Use left as an input signal....declare it as an integer

This, you can.

So my code would be :

entity shifting is

Port ( shift_in : in std_logic;
clk_input : in std_logic;
left : in integer;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is

signal shift_register : std_logic_vector ((left-1) downto 0 );

This, you can't.
I am not able to synthesize this because This signal delcaration
is giving me a synthesis error...It says that left needs to be a
constant instead...

That's why you can't do this.

Any other method to work around this idea?

As Ralf hinted you, you have to implement a register the biggest size
you may need and then take only a slice of it depending on the value of
your input.
Because I need the length of my shift register to change
depending on what i feed the FPGA through the front panel!

An FPGA is definitely NOT software. If you want to be able to shift 3
bits and then 1000 bits, you need a 1000 bits shift register. There is
absolutely No Way around this fact.

Nicolas
 
A

Andy Peters

methi said:
Hi Ralf,

Could I try this instead of using generics:

Use left as an input signal....declare it as an integer

So my code would be :

entity shifting is

Port ( shift_in : in std_logic;
clk_input : in std_logic;
left : in integer;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is


signal shift_register : std_logic_vector ((left-1) downto 0 ):= (others
=> '0');

begin

process(clk_input)
begin
if rising_edge(clk_input) then
shift_register <= shift_register( (left-2) downto 0 ) & shift_in;
shift_out <= shift_register(left-1);
end if;
end process;
end Behavioral;

I am not able to synthesize this because:

signal shift_register : std_logic_vector ((left-1) downto 0 ):= (others
=> '0');

This signal delcaration is giving me a synthesis error...It says that
left needs to be a constant instead...

Yes, it does.
Any other method to work around this idea?

Re-read Ralf's post. His suggestion is a good one.
Because I need the length of my shift register to change depending on
what i feed the FPGA through the front panel!

As Ralf said, "What hardware may provide a 3-bit shift register as well
as a 3000-bit shift register?" When you answer that question, your
path will be clearer!

-a
 
V

valentin tihomirov

signal shift_register : std_logic_vector ( (left-1) downto 0 ):= (others
=> '0');

Natural std_logic_vector range is (1 to length). It is up to you, just some
std functions may malfunction on you vectors.

if rising_edge(clk_input) then
shift_register <= shift_register( (left-2) downto 0 ) & shift_in;
shift_out <= shift_register(left-1);
end if;

I would expell the shift_out line from the procedure as you risk to infere a
FF there, writing it at clk edge. The subject have been answered by others -
you have to allocate a register of sufficient length at compile time and
consume the output from the proper register's cell (addressed by some
integer index input).
 
R

Ralf Hildebrandt

methi wrote:

entity shifting is

Port ( shift_in : in std_logic;
clk_input : in std_logic;
left : in integer;
shift_out : out std_logic);
end shifting;
I am not able to synthesize this because:

signal shift_register : std_logic_vector ((left-1) downto 0 ):= (others
=> '0');

This signal delcaration is giving me a synthesis error...It says that
left needs to be a constant instead...

Any other method to work around this idea?

No other method, but a different description is needed. As I told you,
you need to model a shift register and a multiplexer. For synthesis it
is often a good option, to model such things in an explicit way.

Ok, what is a multiplexer? A real simple description is

process(sel,shift_vector)
begin
case sel is
when 0 => shift_out<=shift_vector(0);
when 1 => shift_out<=shift_vector(1);
....
end case;
end process;


As you can see, this description becomes ugly, if there are a lot of
possible options.

Then there may be the following option (but I am not shure if this will
synthesize well - just test it):

process(sel,shift_vector)
begin
for N in 0 to 99 loop -- assuming a 100 bit shift register
if (N = sel) then
shift_out<=shift_vector(N);
end if;
end loop;
end process;

You may extend this to a size determined by a generic parameter.


Ralf
 
M

methi

valentin said:
=> '0');

Natural std_logic_vector range is (1 to length). It is up to you, just some
std functions may malfunction on you vectors.



I would expell the shift_out line from the procedure as you risk to infere a
FF there, writing it at clk edge. The subject have been answered by others -
you have to allocate a register of sufficient length at compile time and
consume the output from the proper register's cell (addressed by some
integer index input).


Hi,

Where do you suggest I give my shift_out line then....Should I give it
outside the process instead?


I am doing the following according to Ralfs idea:

entity shifting is
Port ( shift_in : in std_logic;
clk_input : in std_logic;
left: in integer;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is


signal shift_register : std_logic_vector (624 downto 0 ):= (others =>
'0');

begin

process(clk_input)

begin
if rising_edge(clk_input) then
shift_register <= shift_register( 623 downto 0 ) & shift_in;

case left is
when 625 => shift_out <= shift_register(624);
when 624 => shift_out <= shift_register(623);
when 623 => shift_out <= shift_register(622);
when 622 => shift_out <= shift_register(621);
when 621 => shift_out <= shift_register(620);
when 620 => shift_out <= shift_register(619);
when 619 => shift_out <= shift_register(618);
when 618 => shift_out <= shift_register(617);
when 617 => shift_out <= shift_register(616);
when 616 => shift_out <= shift_register(615);
when 615 => shift_out <= shift_register(614);
when 614 => shift_out <= shift_register(613);
when 613 => shift_out <= shift_register(612);
when 612 => shift_out <= shift_register(611);
when 611 => shift_out <= shift_register(610);
when 610 => shift_out <= shift_register(609);
when 609 => shift_out <= shift_register(608);
when 608 => shift_out <= shift_register(607);
when 607 => shift_out <= shift_register(606);
when 606 => shift_out <= shift_register(605);
when 605 => shift_out <= shift_register(604);
when 604 => shift_out <= shift_register(603);
when 603 => shift_out <= shift_register(602);
when 602 => shift_out <= shift_register(601);
when 601 => shift_out <= shift_register(600);
when 600 => shift_out <= shift_register(599);
when 599 => shift_out <= shift_register(598);
when 598 => shift_out <= shift_register(597);
when 597 => shift_out <= shift_register(596);
when 596 => shift_out <= shift_register(595);
when 595 => shift_out <= shift_register(594);


when others => NULL;
end case;


end if;
end process;



end Behavioral;
 
M

methi

Ralf said:
methi wrote:




No other method, but a different description is needed. As I told you,
you need to model a shift register and a multiplexer. For synthesis it
is often a good option, to model such things in an explicit way.

Ok, what is a multiplexer? A real simple description is

process(sel,shift_vector)
begin
case sel is
when 0 => shift_out<=shift_vector(0);
when 1 => shift_out<=shift_vector(1);
...
end case;
end process;


As you can see, this description becomes ugly, if there are a lot of
possible options.

Then there may be the following option (but I am not shure if this will
synthesize well - just test it):

process(sel,shift_vector)
begin
for N in 0 to 99 loop -- assuming a 100 bit shift register
if (N = sel) then
shift_out<=shift_vector(N);
end if;
end loop;
end process;

You may extend this to a size determined by a generic parameter.


Ralf



Hi Ralf,

Thank you so much...


I am going to try this out now..instead of the lengthy description...

Methi
 
V

valentin tihomirov

Where do you suggest I give my shift_out line then....Should I give it
outside the process instead?

Yes, writing 'procedure' I was thinking about the process .


when 625 => shift_out <= shift_register(624);
when 624 => shift_out <= shift_register(623);
when 623 => shift_out <= shift_register(622);

Are you insane? Design is all about reuse and avoiding redundancies. All you
need:
shift_out <= shift_register(offset);

.... and do it outside the process. At least outside the clocked loading
block of the process.
 
M

methi

Hi,

I tried this out:

entity shifting is
Port ( shift_in : in std_logic;
clk_input : in std_logic;
left: in integer;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is


signal shift_register : std_logic_vector (624 downto 0 ):= (others =>
'0');

begin

process(clk_input)

begin
if rising_edge(clk_input) then
shift_register <= shift_register( 623 downto 0 ) & shift_in;
end if;
end process;


process(left,shift_register)
begin
for N in 0 to 624 loop -- assuming a 625 bit shift register
if (N = left) then
shift_out <= shift_register(N-1);
end if;
end loop;
end process;



end Behavioral;


My Synthesize dint show ne errors...but it didnt complete


2) I then replaced the second process as follows:

entity shifting is
Port ( shift_in : in std_logic;
clk_input : in std_logic;
left: in integer;
shift_out : out std_logic);
end shifting;

architecture Behavioral of shifting is


signal shift_register : std_logic_vector (624 downto 0 ):= (others =>
'0');

begin

process(clk_input)

begin
if rising_edge(clk_input) then
shift_register <= shift_register( 623 downto 0 ) & shift_in;
end if;
end process;

process(left,shift_register)
begin
shift_out <= shift_register(left-1);
end process;


--process(left,shift_register)
--begin
--for N in 0 to 624 loop -- assuming a 625 bit shift register
-- if (N = left) then
-- shift_out <= shift_register(N);
--end if;
--end loop;
--end process;



end Behavioral;


This is working....PAR is completed successfully...
 
M

Martin Thompson

valentin tihomirov said:
=> '0');

Natural std_logic_vector range is (1 to length). It is up to you, just some
std functions may malfunction on you vectors.

Huh? I've been doing std_logic_vector (msb downto lsb) for years and
never had any problems. I don't think there is any "naturalness"
about doing (1 to something). Or have I misunderstood what you are saying?

Cheers,
Martin
 
M

methi

Hi,

Giving the value of:

shift_out <= shift_register(left-1); within the same process(clk) is
also working fine.....

Methi
 
V

valentin tihomirov

Giving the value of:

shift_out <= shift_register(left-1); within the same process(clk) is
also working fine.....

At first, assigning at clk edge will change funcinonality inferring an FF.
Secondly, shift_out is the entity-wide signal, there is no need to hide it
in the process scope.
 
V

valentin tihomirov

Huh? I've been doing std_logic_vector (msb downto lsb) for years and
never had any problems. I don't think there is any "naturalness"
about doing (1 to something). Or have I misunderstood what you are
saying?

What do you think will be result of

key := ((BS(0) and x"01") sll 6) or ((BS(1)srl 2) and x"3F");

where
subtype BYTE is std_logic_vector (7 downto 0);
type TBYTE_STR is array (0 to 6) of BYTE;
variable BS: TBYTE_STR;
key: BYTE;

Check the "and" and "sll" functions in the std_logic_1164 package, they both
return
VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );

Getting once into trouble, I had to overwrite the standard functions to
return vector having the same range as the first argument.
 
M

Martin Thompson

valentin tihomirov said:
saying?

What do you think will be result of

key := ((BS(0) and x"01") sll 6) or ((BS(1)srl 2) and x"3F");

where
subtype BYTE is std_logic_vector (7 downto 0);
type TBYTE_STR is array (0 to 6) of BYTE;
variable BS: TBYTE_STR;
key: BYTE;

Check the "and" and "sll" functions in the std_logic_1164 package, they both
return
VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );

Well, my std_logic_1164 hasn't got an sll for std_logic_vectors in it
- is this part of VHDL-200x?

Can you explain what you get with your example versus expectation?

Simple ANDing works as I expect in Modelsim 5.8.

Cheers,
Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top