]> rtime.felk.cvut.cz Git - fpga/pwm.git/blob - vector_scale.vhd
Wave_table initialization data format modified.
[fpga/pwm.git] / vector_scale.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_signed.all;
5
6 --------------------------------------------------------------------------------
7
8 entity vector_scale is
9   generic (
10     IRF_ADR_W  : integer := 5;
11     BASE       : integer := 0;
12     SCALE_OFF  : integer := 5;
13     PHASE_BASE : integer := 16;
14     VECTOR_OFF : integer := 0;
15     SCALED_OFF : integer := 1;
16     VECTOR_W   : integer := 10);
17   port (
18     -- Primary slave intefrace
19     ACK_O     : out std_logic;
20     CLK_I     : in  std_logic;
21     RST_I     : in  std_logic;
22     STB_I     : in  std_logic;
23     -- Multiplier interface
24     MUL_A     : out std_logic_vector (15 downto 0);
25     MUL_B     : out std_logic_vector (15 downto 0);
26     MUL_PROD  : in  std_logic_vector (31 downto 0);
27     -- Shared dual-port memory
28     IRF_ACK_I : in  std_logic;
29     IRF_ADR_O : out std_logic_vector (IRF_ADR_W-1 downto 0);
30     IRF_DAT_I : in  std_logic_vector (15 downto 0);
31     IRF_DAT_O : out std_logic_vector (15 downto 0);
32     IRF_STB_O : out std_logic := '0';
33     IRF_WE_O  : out std_logic := '0');
34 end entity vector_scale;
35
36 --------------------------------------------------------------------------------
37
38 architecture behavioral of vector_scale is
39
40   constant SCALE_SUBDIV : integer := 10;
41   
42   type state_t is (ready, load_scale, load_vector, save_scaled, done);
43   subtype irf_adr_t is std_logic_vector (IRF_ADR_W-1 downto 0);
44
45   constant SCALE_ADR  : irf_adr_t := conv_std_logic_vector(BASE + SCALE_OFF, IRF_ADR_W);
46   constant VECTOR_ADR : irf_adr_t := conv_std_logic_vector(PHASE_BASE + VECTOR_OFF, IRF_ADR_W);
47   constant SCALED_ADR : irf_adr_t := conv_std_logic_vector(PHASE_BASE + SCALED_OFF, IRF_ADR_W);
48   
49   signal state : state_t := ready;
50
51   signal INNER_ACK : std_logic := '0';
52
53
54   function twos_to_biased (twos : std_logic_vector) return std_logic_vector is
55     variable result : std_logic_vector (twos'RANGE);
56   begin
57     result := twos;
58     result(result'HIGH) := not twos(twos'HIGH);
59     return result;
60   end;
61
62   function biased_to_twos (biased : std_logic_vector) return std_logic_vector is
63     variable result : std_logic_vector (biased'range);
64   begin
65     result := biased;
66     result(result'HIGH) := not biased(biased'HIGH);
67     return result;
68   end;
69   
70 --------------------------------------------------------------------------------
71
72 begin
73
74   ACK_O <= STB_I and INNER_ACK;
75
76   IRF_DAT_O <= "000000" & twos_to_biased(conv_std_logic_vector(signed(MUL_PROD(15+SCALE_SUBDIV downto SCALE_SUBDIV)), 10));
77
78   
79   FSM : process (CLK_I, RST_I) is
80   begin
81     if rising_edge(CLK_I) then
82       if RST_I = '1' then
83         state     <= ready;
84         INNER_ACK <= '0';
85         IRF_STB_O <= '0';
86         IRF_WE_O  <= '0';
87
88       else
89         case state is
90           when ready =>
91             if STB_I = '1' then
92               state     <= load_scale;
93               IRF_ADR_O <= SCALE_ADR;
94               IRF_STB_O <= '1';
95             end if;
96
97           when load_scale =>
98             state     <= load_vector;
99             IRF_ADR_O <= VECTOR_ADR;
100
101           when load_vector =>
102             state     <= save_scaled;
103             IRF_ADR_O <= SCALED_ADR;
104             MUL_A     <= IRF_DAT_I;
105             
106           when save_scaled =>
107             state     <= done;
108             INNER_ACK <= '1';
109             IRF_WE_O  <= '1';
110             MUL_B     <= conv_std_logic_vector(signed(biased_to_twos(IRF_DAT_I(VECTOR_W-1 downto 0))), 16);
111             
112           when done =>
113             IRF_STB_O <= '0';
114             IRF_WE_O  <= '0';
115             if STB_I = '0' then
116               state     <= ready;
117               INNER_ACK <= '0';
118             end if;
119         end case;
120       end if;
121     end if;
122   end process;
123   
124 end architecture behavioral;
125