OpenCores
URL https://opencores.org/ocsvn/powerseq/powerseq/trunk

Subversion Repositories powerseq

[/] [powerseq/] [trunk/] [powerseq_mod.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 buenos
----------------------------------------------------------------------------------
2
-- Engineer: Istvan Nagy
3
-- Create Date: 10/06/2024 10:10:13 AM 
4
---Version 1.0
5
-- License: 0BSD, no restrictions for use, no need to publish modified versions. 
6
--   The BSD 0-clause license: Copyright (C) 2024 by Istvan Nagy buenoshun@gmail.com 
7
--   Permission to use, copy, modify, and/or distribute this software for any purpose 
8
--   with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND 
9
--   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
10
-- Module Name: powerseq_mod - Behavioral
11
-- Target devices: Microchip Igloo preferred, due to attributes.
12
-- This code is a universal power sequencer block used inside glue logic FPGAs,
13
--  for complex digital boards. It supports up to 128 voltage rails. If less is
14
--  used, then simply tie the powergood inputs fo the unused rails to constant 1.
15
--  The top-level code needs to assign the numbered rail enable/pg signals to 
16
--  actual rail enable/powergood top level ports. For example:
17
--     P1V8SBY_PCH_EN <= PSEQ_RAIL_EN_LOCAL(6);
18
--     PSEQ_RAIL_PG(6) <= P1V8SBY_PCH_PG;
19
--  If a rail failed, the module captures the conditions and shuts all rails down,
20
--  except if we are in "forced power on" mode, then it turns/keeps all rails on.
21
--  The rails that failed will have a '1', rail-254 means thermal shutdown.
22
--  We can slow down the sequence to be able to use TopJtag probe for debugging,
23
--  by making the tick_counter longer, by commenting/uncommenting at the SIG def.
24
--  The module communicates with a power master through all_on and all_pgood.
25
----------------------------------------------------------------------------------
26
library IEEE;
27
use IEEE.STD_LOGIC_1164.ALL;
28
use IEEE.NUMERIC_STD.ALL;
29
library IEEE;
30
use IEEE.STD_LOGIC_1164.ALL;
31
use IEEE.STD_LOGIC_ARITH.ALL;
32
use IEEE.STD_LOGIC_UNSIGNED.ALL;
33
--entity header  ----------------------------------------------------------------
34
entity powerseq_mod is
35
    Port (
36
           clk  : in std_logic; --25MHz clock
37
           reset_n  : in std_logic; --FPGA reset, needs 1ms from standby 3.3V on
38
           forcepoweron  : in std_logic; --from dip switch, avoid failure response
39
           PSEQ_RAIL_EN : out std_logic_vector(127 downto 0); --map to rails
40
           PSEQ_RAIL_PG : in std_logic_vector(127 downto 0); --map to rails
41
           thermal_n : in std_logic; --thermal shutdown, externally combine multiple sources 
42
           failed_rails : out std_logic_vector(255 downto 0); --bits=1 for failed rails
43
           pfailure : out std_logic; --assers during failure --1 if one or more railes failed.
44
           tick_out : out std_logic; --available if needed outside, 1pulse in every several thousand clk
45
           pseqstate_out  : out std_logic_vector(3 downto 0); --we can monitor status through a pin with TopJtag
46
           all_on  : in std_logic; --power master ordered the sequence to commence on
47
           all_pgood: out std_logic --tell the power master that all is on
48
           );
49
end powerseq_mod;
50
 
51
--architecture start ------------------------------------------------------------
52
architecture Behavioral of powerseq_mod is
53
 
54
attribute syn_preserve : boolean;
55
attribute syn_preserve of Behavioral: architecture is true;
56
 
57
-- INTERNAL SIGNALS -------------------------------------------------------------
58
    SIGNAL tick:  std_logic;
59
    SIGNAL tick1:  std_logic;
60
    SIGNAL pseqstate:  std_logic_VECTOR(3 DOWNTO 0);
61
    SIGNAL delay_counter:  std_logic_VECTOR(15 DOWNTO 0);
62
    SIGNAL rail_counter:  integer range 0 to 127;
63
    SIGNAL PSEQ_RAIL_EN_LOCAL : std_logic_vector(127 downto 0);
64
 
65
    SIGNAL tick_counter:  std_logic_VECTOR(15 DOWNTO 0); --counts ticks of 40us, normal operation
66
    --SIGNAL tick_counter:  std_logic_VECTOR(21 DOWNTO 0); --counts ticks of 2.5ms, for board debug
67
    --SIGNAL tick_counter:  std_logic_VECTOR(3 DOWNTO 0); --counts ticks of 640ns for simulation
68
 
69
--architecture body start -------------------------------------------------------
70
begin
71
 
72
pseqstate_out <= pseqstate;
73
PSEQ_RAIL_EN <= PSEQ_RAIL_EN_LOCAL;
74
 
75
process (clk, reset_n)
76
begin
77
if (reset_n='0') then
78
   pseqstate <= (others => '0');
79
   tick <= '0';
80
   tick1 <= '0';
81
   tick_out <= '0';
82
   tick_counter <= (others => '0');
83
   delay_counter <= (others => '0');
84
   rail_counter <= 0;
85
   all_pgood <= '0';
86
   PSEQ_RAIL_EN_LOCAL <= (others => '0');
87
   failed_rails <= (others => '0');
88
   pfailure <= '0';
89
else
90
  if (clk'event and clk = '1') then
91
     tick_counter <= tick_counter +1;
92
     if (tick_counter = 0) then tick1 <= '1'; else tick1 <= '0'; end if;
93
     tick <= tick1;
94
     tick_out <= tick1;
95
     if (tick='1') then
96
        case ( pseqstate ) is
97
 
98
              when "0000" => --after reset (S5 standby)             
99
                if (all_on='1' or forcepoweron='1') then pseqstate <= "0001"; end if; --master commanded power up    
100
                all_pgood <= '0';
101
                delay_counter <= (others => '0');
102
                rail_counter <= 0;
103
                pfailure <= '0';
104
                failed_rails <= (others => '0');
105
 
106
              when "0001" => --sequencing up temporary state (S5->S0)            
107
                all_pgood <= '0';
108
                PSEQ_RAIL_EN_LOCAL(rail_counter) <= '1';
109
                if (PSEQ_RAIL_PG(rail_counter)='1') then  --rail pg is asserted          
110
                    delay_counter  <= (others => '0');
111
                    if (rail_counter = 127) then --last one       
112
                       pseqstate <= "0011";  --fully on state    
113
                    else --not the last one yet, step to next     
114
                       rail_counter <= rail_counter +1;
115
                    end if;
116
                elsif (delay_counter="0111111111111111") then --rail failed with 1.3s timeout          
117
                  if (forcepoweron='1') then --if forced then continue after timeout       
118
                    delay_counter  <= (others => '0');
119
                    if (rail_counter = 127) then --last one       
120
                       pseqstate <= "0011";  --fully on state    
121
                    else --not the last one yet, step to next     
122
                       rail_counter <= rail_counter +1;
123
                    end if;
124
                  else  --if not forced then make it fail after timeout     
125
                    pseqstate <= "0111"; --failed state         
126
                    delay_counter  <= (others => '0');
127
                    pfailure <= '1';
128
                    failed_rails(rail_counter) <= '1';
129
                  end if;
130
                else --waiting                
131
                   delay_counter <= delay_counter +1;
132
                end if;
133
 
134
              when "0011" => --fully on stable state (S0)            
135
                delay_counter <= (others => '0');
136
                all_pgood <= '1';
137
                if (forcepoweron='0' and all_on='0') then  --master commanded power down        
138
                    pseqstate <= "0010";
139
                    rail_counter <= 127;
140
                elsif (forcepoweron='0' and PSEQ_RAIL_PG /= PSEQ_RAIL_EN_LOCAL) then --a rail that was already on now failed    
141
                    failed_rails(127 downto 0) <=  not PSEQ_RAIL_PG;
142
                    pseqstate <= "0111";
143
                    pfailure <= '1';
144
                elsif (forcepoweron='0' and thermal_n = '0') then  --overheating shutdown
145
                    failed_rails(254) <= '1'; --rail-254 means thermal       
146
                    pseqstate <= "0111";
147
                    pfailure <= '1';
148
                end if;
149
 
150
              when "0010" => --sequencing down temporary state (S0->S5)            
151
                --all_pgood <= '0';   --if we want pgood to go away sooner     
152
                PSEQ_RAIL_EN_LOCAL(rail_counter) <= '0';
153
                if (delay_counter="0000000001111101") then --5ms delay             
154
                    delay_counter  <= (others => '0');
155
                    if (rail_counter = 0) then --last one       
156
                       pseqstate <= "0000";  --standby state     
157
                    else --not the last one yet, step to next     
158
                       rail_counter <= rail_counter -1;
159
                    end if;
160
                else --waiting                
161
                   delay_counter <= delay_counter +1;
162
                end if;
163
 
164
              when "0111" => --error state               
165
                all_pgood <= '0';
166
                PSEQ_RAIL_EN_LOCAL <= (others => '0'); --turn off stay off until input pcycle     
167
                if (all_on='0') then pseqstate <= "0000"; end if; --master commanded power down    
168
 
169
              when others =>
170
                  pseqstate <= "0000";
171
         end case;
172
      end if;
173
   end if;
174
end if;
175
end process;
176
 
177
--end file ----------------------------------------------------------------------
178
end Behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.