Archive

Posts Tagged ‘VHDL’

VHDL Reset

July 27th, 2010 No comments

In most HW systems you need a way to do a system reset, but you obviously don’t want your reset line to miss fire and kill your system. Also, you don’t want to deal with multiple resets due to bouncing. And depending on your operating environment, you may need to protect your resets from SEI’s from radiation or whatever.

Below details a simple solution to debounce and enforce a minimum reset hold time in your code.

——

I use Generics in my entity so I can set the sys clk rate and the minimum width for the reset pulse easily:

entity rst_detect is
generic(
clk_rate_mhz : integer := 20000000;
min_width_us : integer := 10000
);
port(
clk     : in std_logic;
rst_in  : in std_logic;
rst_out : out std_logic
);
end entity

architecture rtl of por_detect is

– to get the minimum ticks for a valid por,

– find the ticks per 1MHz (or 1us) and then

– multiply by the min us value

constant MIN_TICKS : integer := integer(ceil(real((clk_rate_mhz/1000000)*min_width_us)));

– min bit width of the counter for to count to min_ticks

constant COUNTER_WID : integer := integer(ceil(log2(real(MIN_TICKS))));

constant MAX_COUNT : integer := integer((2**COUNTER_WID) – 1);

signal count : std_logic_vector(COUNTER_WID – 1 downto 0) := (others => ’0′);

–start and stop counter vals

signal s_count : std_logic_vector(COUNTER_WID – 1 downto 0);

type   por_state_t is (POR_IDLE, POR_WAIT, POR_OUTPUT);

signal por_state : por_state_t := POR_IDLE;

begin

counter : process(clk) begin

if(rising_edge(clk)) then

count <= count + 1;

end if;

end process;

por_det : process(clk) begin

if(rising_edge(clk)) then

case por_state is

when POR_IDLE =>

por_out <= ’0′;

if(por_in = ’1′) then

s_count   <= count;

por_state <= POR_WAIT;

else

por_state <= POR_IDLE;

end if;

when POR_WAIT =>

if(por_in = ’0′) then

por_state <= POR_IDLE;

else

if(count > s_count) then

if(count – s_count >= MIN_TICKS) then

por_out   <= ’1′;

por_state <= POR_OUTPUT;

else

por_state <= POR_WAIT;

end if;

else

if((MAX_COUNT – s_count) + count >= MIN_TICKS) then

por_out   <= ’1′;

por_state <= POR_OUTPUT;

else

por_state <= POR_WAIT;

end if;

end if;

end if;

when POR_OUTPUT =>

if(por_in = ’0′) then

por_out <= ’0′;

por_state <= POR_IDLE;

else

por_state <= POR_OUTPUT;

end if;

when others =>

por_out   <= ’0′;

por_state <= POR_IDLE;

end case;

end if;
end process;

end architecture rtl

Categories: Code, Uncategorized Tags:

VHDL inferred gating

February 3rd, 2010 No comments

So this was an interesting find. We have been working with a rather large VHDL code base, and noticed a huge amount of control logic was being generated during synthesis. It seems that part of this is due to an interesting “feature” of VHDL, or I suppose more exactly of synthesis tools (we saw this with XST and Synplicity).

If you have some case statement, if then else, or switch, etc. Look carefully at signal assignments in each of the various cases. We were not always assigning to each signal in every case. This obviously follows from different cases doing different things.. but here is the tricky part. Clock gating and/or registering of signals is *inferred* for any signal that is not assigned to in all cases!

This can eat up logic fast, and if you are running near capacity of your target device, it can make it even worse, the added logic, clocking, and routing can cause the implementation to balloon. For example targeting an LX110-T, if we went above ~80% utilization, by the time we got through mapping and place&route we were close to 95%. The only way we could account for this was the extra logic used for the inferred control signals.

This may not matter in a lot of designs where you have plenty of room in the part, or maybe you don’t for some reason have a lot of case statements. We ended up refactoring and just assigning a signal to itself or some don’t care value in the other cases.

Categories: Algorithm, Code, Embedded, Xilinx Tags: , ,