valentin said:
Indeed, if ASYNC_RESET is True then there is two resets in the circuit. This
wouldn't add extra logic:
if ASYNC_RESET and RESET = '1' then
REGs <= SEED;
elsif Rising_Edge(Clk) then
if ENABLE = '1' then
if not ASYNC_RESET and RESET = '1' then
REGs <= SEED;
elsif
...
A never-called reset block will be optimized out.
YMMV. I would not want to predict if this
confused a synthesis tool or not and whether
it would work on all synthesis tools.
A_RST: if ASYNC_RESET generate
process (CLK, RESET)
if RESET = '1' then
REGs <= SEED;
elsif Rising_Edge(Clk) then
if ENABLE = '1' then
REGs <= REG_NEXT;
end if;--en
end if;--clk,rst
end generate;
S_RST: if not ASYNC_RESET generate
process (CLK, RESET)
elsif Rising_Edge(Clk) then
if ENABLE = '1' then
if RESET = '1' then
REGs <= SEED;
else
REGs <= REG_NEXT;
end if; -- rst
end if; -- en
end if; --clk
end generate;
Seems, it is more cumbersome (like copy&paste vs. polymorpism). But is
anybody tells it is the only reliable solution....
This would work, but yikes, it is alot of typing.
If you need the ability to switch between registers
that are asynchronous reset and synchronous reset,
how about a package with the registers implemented as
procedures? Note this may not be synthesizable on all
ASIC synthesis tools yet, but it is in the lastest
version of 1076.6 (the IEEE VHDL RTL Synthesis standard).
Packages shown below. Usage as follows:
-- Asynchronous Reset
use work.AsyncRegisterPkg.all ;
....
DFFRLE(CLK, not RESET, ENABLE, REG_NEXT, REGs, SEED) ;
-- Synchronous Reset
use work.SyncRegisterPkg.all ;
....
DFFRLE(CLK, not RESET, ENABLE, REG_NEXT, REGs, SEED) ;
You can also call procedures by named association:
DFFRLE(
Clk => CLK,
nReset => not RESET,
enable => ENABLE,
D => REG_NEXT,
Q => REGs,
ResetVal => SEED
) ;
From a standards point of view, we could and probably
should have things like this standardized and freely
available. It would be nice if the register names were
somewhat familiar to some group of people. Hence,
have names similar to ASIC/FPGA library names or have
names similar to older HDLs that had things like this
(ie CUPL/ABLE/PALASM/...). To get these standardized
it is a matter of getting users that are interested in
working on them (I for one am interested, have some
ideas, and have a reasonable understanding of how IEEE
standards groups work - however - at least near term,
I am tied up with VHDL-200X work).
If you are following VHDL-200X, we do have a new feature
that will help some with design wide package switching.
Check out:
http://www.eda.org/vhdl-200x/vhdl-200x-ft/proposals/
the proposal is FT16 - please note documentation on
it is still a work in progress - so be kind in your
constuctive comments.
Package definitions follow for the above functionality.
Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:
[email protected]
SynthWorks Design Inc.
http://www.SynthWorks.com
1-503-590-4787
Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package AsyncRegisterPkg is
....
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic ;
signal Q : out Std_Logic ;
ResetVal : in Std_logic := '0'
) ;
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic_Vector ;
signal Q : out Std_Logic_vector ;
ResetVal : in Std_Logic_Vector := (others => '0')
) ;
end package ;
package body AsyncRegisterPkg is
....
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic ;
signal Q : out Std_Logic ;
ResetVal : in Std_Logic := '0'
) is
begin
if nReset = '0' then
Q <= ResetVal ;
elsif rising_edge(Clk) then
if enable = '1' then
Q <= D;
end if ;
end if;
end DFF;
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic_Vector ;
signal Q : out Std_Logic_vector ;
ResetVal : in Std_Logic_Vector := (others => '0')
) is
begin
if nReset = '0' then
Q <= ResetVal ;
elsif rising_edge(Clk) then
if enable = '1' then
Q <= D;
end if ;
end if;
end DFF;
end package ;
package SyncRegisterPkg is
....
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic ;
signal Q : out Std_Logic ;
ResetVal : in Std_logic := '0'
) ;
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic_Vector ;
signal Q : out Std_Logic_vector ;
ResetVal : in Std_Logic_Vector := (others => '0')
) ;
end package ;
package body SyncRegisterPkg is
....
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic ;
signal Q : out Std_Logic ;
ResetVal : in Std_Logic := '0'
) is
begin
if rising_edge(Clk) then
if nReset = '0' then
Q <= ResetVal ;
elsif enable = '1' then
Q <= D;
end if ;
end if;
end DFF;
procedure DFFRLE(
signal Clk : in Std_Logic ;
nReset : in Std_Logic ;
enable : in Std_Logic ;
D : in Std_Logic_Vector ;
signal Q : out Std_Logic_vector ;
ResetVal : in Std_Logic_Vector := (others => '0')
) is
begin
if rising_edge(Clk) then
if nReset = '0' then
Q <= ResetVal ;
elsif enable = '1' then
Q <= D;
end if ;
end if;
end DFF;
end package ;