simpler stuff!!!

R

rickman

It has been awhile since I coded up any VHDL and there are some things
I have forgotten. One of them is how to infer the GSR state of a
register. What I remember is that you use an async reset on all
registers and specify the state in an assignment in that part of the
if statement. But I have always had an external reset to use as the
controlling signal for the reset state. What do you use if you have
no external reset and only want to specify the reset state for the
power on reset?

Here is code I am currently using.

GSR <= not Switch(5);

SysReset <= SysRst(0);
SysRstReg: process (GenClk, GSR) begin
if (GSR = '1') then
SysRst <= "1111";
elsif (rising_edge(GenClk)) then
SysRst <= '0' & SysRst(3 downto 1);
end if;
end process SysRstReg;

But if I don't have the input Switch(5), what do I specify? This is
for a Lattice part which should be very similar to the Xilinix parts
since they share the same hardware and software roots. I have dug all
through the Lattice docs and found lots of info on how to *control*
the GSR/PUR signal, but not on how to *use* the GSR signal.

Rick
 
K

KJ

It has been awhile since I coded up any VHDL and there are some things
I have forgotten.  One of them is how to infer the GSR state of a
register.  What I remember is that you use an async reset on all
registers and specify the state in an assignment in that part of the
if statement.  But I have always had an external reset to use as the
controlling signal for the reset state.  What do you use if you have
no external reset and only want to specify the reset state for the
power on reset?

Here is code I am currently using.

  GSR <= not Switch(5);

  SysReset <= SysRst(0);
  SysRstReg: process (GenClk, GSR) begin
        if (GSR = '1') then
          SysRst <= "1111";
        elsif (rising_edge(GenClk)) then
          SysRst <= '0' & SysRst(3 downto 1);
        end if;
  end process SysRstReg;

But if I don't have the input Switch(5), what do I specify?  This is
for a Lattice part which should be very similar to the Xilinix parts
since they share the same hardware and software roots.  I have dug all
through the Lattice docs and found lots of info on how to *control*
the GSR/PUR signal, but not on how to *use* the GSR signal.

Rick

Assuming the Lattice tools support signal initializers, then the way
you handle it is by specifying an initial value for the 'SysRst'
vector

signal SysRst: std_logic_vector(3 downto 0) := (others => '1');

Kevin Jennings
 
R

rickman

Assuming the Lattice tools support signal initializers, then the way
you handle it is by specifying an initial value for the 'SysRst'
vector

signal SysRst: std_logic_vector(3 downto 0) := (others => '1');

Kevin Jennings

Good point, but I don't know if it will work. I do know that
historically this has been frowned upon in general, but I think that
is because it only specifies the power up reset state and can leave
the designer thinking he has provided a true reset when such is not
the case.

I want to say that I have seen some tools use the initialization value
as the asynch reset state, but I don't recall which.

Rick
 
K

KJ

Good point, but I don't know if it will work.

As long as...
1. The physical device has a guaranteed powerup state for flops
2. The tools support initial values

then it will work. As you no doubt know, those are two big 'ifs' that
you need to get the answer to before using it. If not, then you'll
need to provide some external signal (even an otherwise unused signal
pulled up or down to a valid logic level will do the trick) to provide
the 'external reset' to the FPGA.
I do know that
historically this has been frowned upon in general, but I think that
is because it only specifies the power up reset state and can leave
the designer thinking he has provided a true reset when such is not
the case.

Correct, you don't want to have to sprinkle your code with initial
values in case you end up targetting a device that violates #1 or
using a tool that violates #2.

KJ
 
J

jens

then it will work. As you no doubt know, those are two big 'ifs' that
you need to get the answer to before using it. If not, then you'll
need to provide some external signal (even an otherwise unused signal
pulled up or down to a valid logic level will do the trick) to provide
the 'external reset' to the FPGA.

That would be quite a trick! :) An unused pull-up/down will either
hold the FPGA in perma-reset or not provide a reliable power-on
reset. The only way to generate a reliable power-on reset for an FPGA
that doesn't have its own is to use a carefully designed analog reset
or use an IC that's designed to do that.

Yes, I have successfully designed a non-carefully designed analog
reset.
 
K

KJ

jens said:
That would be quite a trick! :) An unused pull-up/down will either
hold the FPGA in perma-reset or not provide a reliable power-on
reset. The only way to generate a reliable power-on reset for an FPGA
that doesn't have its own is to use a carefully designed analog reset
or use an IC that's designed to do that.

The trick is that the external reset pin is not really providing a reset,
the logic level that it's providing is always a 'not reset'...but the code
in the FPGA doesn't know that. To provide an internal logic reset at power
up without an external (carefully designed reset) IC you need a device and
tool set that supports assignment of initial values.

signal Reset_Shift_Reg: std_ulogic_vector(3 downto 0) := (others => '1');
....
Fpga_Reset <= Reset_Shift_Reg(3);

where Reset_Shift_Reg will shift in a constant of '0' into the low end.
This will give you a couple clock cycle wide Fpga_Reset signal. But if your
synthesis tools are too smart in their optomization they could optomize the
whole shift register thing away replacing it with '0' and essentially
prevent you from getting any reset.

If that situation arises, then usually you can work around this by adding
attributes to tell it not to optomize the shift register logic. If that
still doesn't work then you could change your code so that the input from
the shift register is not a constant of '0' but instead comes from a pin
(that you pull down on the board, nothing fancy needed). In that situation
the synthesis tool would not be able to optomize anything the shift register
would remain intact. Since the pin is pulled to the 'not reset' logic level
it will get shifted through bringing the FPGA out of reset.

I used this trick once before years ago when the stars aligned just so
meeting all of the criteria that I mentioned. Now-a-daze the tools might
not be so unforgiving so you might not need this idea, but it does work and
works reliably as well.
Yes, I have successfully designed a non-carefully designed analog
reset.

You should've thought of it as a carefully designed 'not reset' instead ;)

Kevin Jennings
 
A

Andy

The trick is that the external reset pin is not really providing a reset,
the logic level that it's providing is always a 'not reset'...but the code
in the FPGA doesn't know that. To provide an internal logic reset at power
up without an external (carefully designed reset) IC you need a device and
tool set that supports assignment of initial values.

signal Reset_Shift_Reg: std_ulogic_vector(3 downto 0) := (others => '1');
...
Fpga_Reset <= Reset_Shift_Reg(3);

where Reset_Shift_Reg will shift in a constant of '0' into the low end.
This will give you a couple clock cycle wide Fpga_Reset signal. But if your
synthesis tools are too smart in their optomization they could optomize the
whole shift register thing away replacing it with '0' and essentially
prevent you from getting any reset.

If that situation arises, then usually you can work around this by adding
attributes to tell it not to optomize the shift register logic. If that
still doesn't work then you could change your code so that the input from
the shift register is not a constant of '0' but instead comes from a pin
(that you pull down on the board, nothing fancy needed). In that situation
the synthesis tool would not be able to optomize anything the shift register
would remain intact. Since the pin is pulled to the 'not reset' logic level
it will get shifted through bringing the FPGA out of reset.

I used this trick once before years ago when the stars aligned just so
meeting all of the criteria that I mentioned. Now-a-daze the tools might
not be so unforgiving so you might not need this idea, but it does work and
works reliably as well.


You should've thought of it as a carefully designed 'not reset' instead ;)

Kevin Jennings

That shift register will only work if you can reliably define the
initial state of the registers within it.

That is the whole problem being adressed: Some targets (ASICs) do not
support known power up states on registers.

Thankfully, most FPGAs do. Most tools will initialize a register to
its reset value anyway, so a reset clause that ends up getting
optimized away (due to being driven with a constant) will usually
still result in the same initialization of the register at the end of
configuration.

Andy
 
K

KJ

That shift register will only work if you can reliably define the
initial state of the registers within it.

I said that in an earlier post (May 20).
That is the whole problem being adressed: Some targets (ASICs) do not
support known power up states on registers.

Then you're reading a whole different problem than what rickman
posted.
Thankfully, most FPGAs do. Most tools will initialize a register to
its reset value anyway, so a reset clause that ends up getting
optimized away (due to being driven with a constant) will usually
still result in the same initialization of the register at the end of
configuration.

I disagree, any 'optomization' will likely break it. The initial
value specified for the shift register will always be the opposite
polarity of the constant that is being driven into the shift
register. In any case, that is a situation where the tool chain
doesn't provide the support which violates criteria #2 from my May 20
post...or it could also be interpreted as a synthesis optomization bug
to be reported to the vendor.

Kevin Jennings
 
R

rickman

where Reset_Shift_Reg will shift in a constant of '0' into the low end.
This will give you a couple clock cycle wide Fpga_Reset signal. But if your
synthesis tools are too smart in their optomization they could optomize the
whole shift register thing away replacing it with '0' and essentially
prevent you from getting any reset.

If the synthesis software "optimizes" the shift register away, it is
not optimizing, it is malfunctioning. When tools optimize, they
replace circuitry with equivalent circuitry which uses less
resources. Obviously no shift register is not equivalent to a shift
register in this case. The tools won't optimize this away.

The problem is that the global async reset provided in an FPGA is not
at all useful as a global async reset. Or more accurately, it is not
a very good release from reset. It has to be released from reset
synchronously to prevent part of a state machine from starting without
the rest of it. For example, a one-hot encoded FSM might have the
initial hot deselect but the next hot, which is still seeing the
reset, not be asserted. This leaves the FSM in a "no-hot" state.

So you can't rely on the global async reset to release the entire chip
at the right time unless it is synchronized to the appropriate clock.
That is what the shift register does. The good thing about the shift
register is that it itself is not subject to any issues with the
timing of the async reset release. All that will do is to possibly
extend the duration of the reset by one clock.

Rick
 
K

KJ

rickman said:
If the synthesis software "optimizes" the shift register away, it is
not optimizing, it is malfunctioning. When tools optimize, they
replace circuitry with equivalent circuitry which uses less
resources. Obviously no shift register is not equivalent to a shift
register in this case. The tools won't optimize this away.
A shift register that has an input of '0' can be optomized away and simply
replaced with '0' if that shift register has no non-'0' initial values
specified. A tool that doesn't support initial values will do exactly that.
I agree that the tools "shouldn't" do that, but you would be wrong in
assuming that they "won't" do that. Some not to be named tools used to do
just that, one should verify before assuming that the particular tool that
you're using doesn't do that.

This...
q <= d when rising_edge(clock)
d <= '0';

is equivalent to this...
q <= '0';

If you have...
signal q: std_ulogic;

but not if you have...
signal q: std_ulogic := '1';

The method I was tossed out was a way to generate a synchronous reset
without any input pins but it requires support from both the device and the
tools...without both it won't work. It's also useful in generating multiple
resets that are each synchronous to some internal set of clocks (i.e.
reset_clk1, reset_clk2, etc.)
The problem is that the global async reset provided in an FPGA is not
at all useful as a global async reset. Or more accurately, it is not
a very good release from reset. It has to be released from reset
synchronously to prevent part of a state machine from starting without
the rest of it.

That's why I don't bother with async resets at all unless it presents some
actual advantage in terms of logic/routing usage in the particular device
I'm targetting (generally it does not)....the reset signal still needs to be
generated synchronously....and then those dang dual clock fifos...sigh...oh
well.

Kevin Jennings
 

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,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top