]> rtime.felk.cvut.cz Git - fpga/pwm.git/blob - irc_base.vhd
Wave_table initialization data format modified.
[fpga/pwm.git] / irc_base.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5
6 --------------------------------------------------------------------------------
7
8 entity irc_base is
9   generic (
10     IRF_ADR_W : integer := 5;
11     BASE      : integer := 0;
12     IRC_OFF   : integer := 1;
13     ABASE_OFF : integer := 2;
14     APER_OFF  : integer := 3;
15     A_OFF     : integer := 4);
16   port (
17     -- Primary slave interface
18     ACK_O     : out std_logic := '0';
19     CLK_I     : in  std_logic;
20     RST_I     : in  std_logic;
21     STB_I     : in  std_logic;
22     -- Master interface to the interface memory
23     IRF_ACK_I : in  std_logic;
24     IRF_ADR_O : out std_logic_vector (IRF_ADR_W-1 downto 0);
25     IRF_DAT_I : in  std_logic_vector (15 downto 0);
26     IRF_DAT_O : out std_logic_vector (15 downto 0);
27     IRF_STB_O : out std_logic := '0';
28     IRF_WE_O  : out std_logic := '0';
29     -- Error flag
30     BAD_BASE : out std_logic);
31 end entity irc_base;
32
33 --------------------------------------------------------------------------------
34
35 architecture behavioral of irc_base is
36
37   type state_t is (ready, nop, load_irc, load_base, load_per, do_correction, save, done);
38   subtype irf_adr_t is std_logic_vector (IRF_ADR_W-1 downto 0);
39
40   constant IRC_ADR  : irf_adr_t := conv_std_logic_vector(BASE+IRC_OFF, IRF_ADR_W);
41   constant BASE_ADR : irf_adr_t := conv_std_logic_vector(BASE+ABASE_OFF, IRF_ADR_W);
42   constant PER_ADR  : irf_adr_t := conv_std_logic_vector(BASE+APER_OFF, IRF_ADR_W);
43   constant ANG_ADR  : irf_adr_t := conv_std_logic_vector(BASE+A_OFF, IRF_ADR_W);
44
45   
46   signal state    : state_t := ready;
47   signal irc      : std_logic_vector (15 downto 0);
48   signal irc_base : std_logic_vector (15 downto 0);
49   signal irc_per  : std_logic_vector (15 downto 0);
50
51   signal angle    : std_logic_vector (15 downto 0);
52   signal new_base : std_logic_vector (15 downto 0);
53   signal lower    : std_logic;
54   signal higher   : std_logic;
55
56 --------------------------------------------------------------------------------
57   
58 begin
59
60   BAD_BASE <= '1' when state = save and (lower = '1' or higher = '1') else '0';
61   
62   lower  <= angle (angle'HIGH);
63   higher <= '1' when angle >= irc_per and lower = '0' else '0';
64
65   angle <= irc - irc_base;
66   
67   new_base <= irc_base - irc_per when lower = '1' else
68               irc_base + irc_per when higher = '1' else
69               irc_base;
70   
71   
72   FSM : process (CLK_I) is
73   begin
74     if rising_edge(CLK_I) then
75       if RST_I = '1' or STB_I = '0' then
76         state     <= ready;
77         ACK_O     <= '0';
78         IRF_STB_O <= '0';
79         IRF_WE_O  <= '0';
80
81       else
82         case state is
83           when ready =>
84             if STB_I = '1' then
85               state     <= nop;
86               IRF_ADR_O <= IRC_ADR;
87               IRF_STB_O <= '1';
88             end if;
89
90           when nop =>
91             state <= load_irc;
92             IRF_ADR_O <= BASE_ADR;
93             
94           when load_irc =>
95             state     <= load_base;
96             irc       <= IRF_DAT_I;
97             IRF_ADR_O <= PER_ADR;
98
99           when load_base =>
100             state <= load_per;
101             irc_base  <= IRF_DAT_I;
102             
103           when load_per =>
104             state     <= do_correction;
105             irc_per   <= IRF_DAT_I;
106             IRF_STB_O <= '0';
107
108           when do_correction =>
109             state     <= save;
110             irc_base  <= new_base;
111             IRF_ADR_O <= BASE_ADR;
112             IRF_DAT_O <= new_base;
113             IRF_STB_O <= '1';
114             IRF_WE_O  <= '1';
115
116           when save =>
117             state     <= done;
118             IRF_ADR_O <= ANG_ADR;
119             IRF_DAT_O <= angle;
120             ACK_O     <= '1';
121             
122           when done =>
123             IRF_STB_O <= '0';
124             IRF_WE_O  <= '0';
125             if STB_I = '0' then
126               state <= ready;
127               ACK_O <= '0';
128             end if;
129         end case;
130
131       end if;
132     end if;
133   end process;
134
135 end architecture behavioral;
136