Generic shift register where value 'n' keeps changing

M

methi

Guest
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
 
Ralf Hildebrandt wrote:
methi wrote:

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

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
 
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
 
methi wrote:
Ralf Hildebrandt wrote:
What hardware may provide a 3-bit shift register as well as a 3000-bit
shift register? A 3000-bit shift register I guess... ;-)

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).


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
 
valentin tihomirov wrote:
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).

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;
 
Ralf Hildebrandt wrote:
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


Hi Ralf,

Thank you so much...


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

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...
 
Hi,

Giving the value of:

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

Methi
 

Welcome to EDABoard.com

Sponsor

Back
Top