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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [vdsm8.vhd] - Blame information for rev 218

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 218 jshamlet
-- Copyright (c)2020 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
--
24
-- VHDL Units :  vdsm8
25
-- Description:  8-bit variable delta-sigma modulator single-bit DAC
26
 
27
library ieee;
28
use ieee.std_logic_1164.all;
29
use ieee.std_logic_unsigned.all;
30
use ieee.std_logic_arith.all;
31
 
32
entity vdsm8 is
33
generic(
34
  Reset_Level           : std_logic := '1';
35
  -- Do not adjust alone! DELTA constants must be
36
  --  changed as well.
37
  DAC_Width             : integer := 8
38
);
39
port(
40
  Clock                 : in  std_logic;
41
  Reset                 : in  std_logic;
42
  DACin                 : in  std_logic_vector(DAC_Width-1 downto 0);
43
  DACout                : out std_logic
44
);
45
end entity;
46
 
47
architecture behave of vdsm8 is
48
 
49
  function ceil_log2 (x : in natural) return natural is
50
    variable retval     : natural;
51
  begin
52
    retval              := 1;
53
    while ((2**retval) - 1) < x loop
54
      retval            := retval + 1;
55
    end loop;
56
    return retval;
57
  end function;
58
 
59
  constant DELTA_1_I    : integer := 1;
60
  constant DELTA_2_I    : integer := 5;
61
  constant DELTA_3_I    : integer := 25;
62
  constant DELTA_4_I    : integer := 75;
63
  constant DELTA_5_I    : integer := 125;
64
  constant DELTA_6_I    : integer := 195;
65
 
66
  constant DELTA_1      : std_logic_vector(DAC_Width-1 downto 0) :=
67
                           conv_std_logic_vector(DELTA_1_I, DAC_Width);
68
  constant DELTA_2      : std_logic_vector(DAC_Width-1 downto 0) :=
69
                           conv_std_logic_vector(DELTA_2_I, DAC_Width);
70
  constant DELTA_3      : std_logic_vector(DAC_Width-1 downto 0) :=
71
                           conv_std_logic_vector(DELTA_3_I, DAC_Width);
72
  constant DELTA_4      : std_logic_vector(DAC_Width-1 downto 0) :=
73
                           conv_std_logic_vector(DELTA_4_I, DAC_Width);
74
  constant DELTA_5      : std_logic_vector(DAC_Width-1 downto 0) :=
75
                           conv_std_logic_vector(DELTA_5_I, DAC_Width);
76
  constant DELTA_6      : std_logic_vector(DAC_Width-1 downto 0) :=
77
                           conv_std_logic_vector(DELTA_6_I, DAC_Width);
78
 
79
  constant MAX_PERIOD   : integer := 2**DAC_Width;
80
  constant DIV_WIDTH    : integer := DAC_Width * 2;
81
 
82
  constant PADJ_1_I     : integer := DELTA_1_I * MAX_PERIOD;
83
  constant PADJ_2_I     : integer := DELTA_2_I * MAX_PERIOD;
84
  constant PADJ_3_I     : integer := DELTA_3_I * MAX_PERIOD;
85
  constant PADJ_4_I     : integer := DELTA_4_I * MAX_PERIOD;
86
  constant PADJ_5_I     : integer := DELTA_5_I * MAX_PERIOD;
87
  constant PADJ_6_I     : integer := DELTA_6_I * MAX_PERIOD;
88
 
89
  constant PADJ_1       : std_logic_vector(DIV_WIDTH-1 downto 0) :=
90
                           conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
91
  constant PADJ_2       : std_logic_vector(DIV_WIDTH-1 downto 0) :=
92
                           conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
93
  constant PADJ_3       : std_logic_vector(DIV_WIDTH-1 downto 0) :=
94
                           conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
95
  constant PADJ_4       : std_logic_vector(DIV_WIDTH-1 downto 0) :=
96
                           conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
97
  constant PADJ_5       : std_logic_vector(DIV_WIDTH-1 downto 0) :=
98
                           conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
99
  constant PADJ_6       : std_logic_vector(DIV_WIDTH-1 downto 0) :=
100
                           conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
101
 
102
  signal DACin_q        : std_logic_vector(DAC_Width-1 downto 0);
103
 
104
  signal Divisor        : std_logic_vector(DIV_WIDTH-1 downto 0);
105
  signal Dividend       : std_logic_vector(DIV_WIDTH-1 downto 0);
106
 
107
  signal q              : std_logic_vector(DIV_WIDTH*2-1 downto 0);
108
  signal diff           : std_logic_vector(DIV_WIDTH downto 0);
109
 
110
  constant CB           : integer := ceil_log2(DIV_WIDTH);
111
  signal count          : std_logic_vector(CB-1 downto 0);
112
 
113
  signal Next_Width     : std_logic_vector(DAC_Width-1 downto 0);
114
  signal Next_Period    : std_logic_vector(DAC_Width-1 downto 0);
115
 
116
  signal PWM_Width      : std_logic_vector(DAC_Width-1 downto 0);
117
  signal PWM_Period     : std_logic_vector(DAC_Width-1 downto 0);
118
 
119
  signal Width_Ctr      : std_logic_vector(DAC_Width-1 downto 0);
120
  signal Period_Ctr     : std_logic_vector(DAC_Width-1 downto 0);
121
 
122
begin
123
 
124
  diff                  <= ('0' & q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
125
                           ('0' & Divisor);
126
 
127
  Dividend   <= PADJ_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
128
                PADJ_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
129
                PADJ_4 when DACin_q >= DELTA_4_I and DACin_q < DELTA_5_I else
130
                PADJ_5 when DACin_q >= DELTA_5_I and DACin_q < DELTA_6_I else
131
                PADJ_6 when DACin_q >= DELTA_6_I else
132
                PADJ_1;
133
 
134
  Next_Width <= DELTA_1 when DACin_q >= DELTA_1_I and DACin_q < DELTA_2_I else
135
                DELTA_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
136
                DELTA_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
137
                DELTA_4 when DACin_q >= DELTA_4_I and DACin_q < DELTA_5_I else
138
                DELTA_5 when DACin_q >= DELTA_5_I and DACin_q < DELTA_6_I else
139
                DELTA_6 when DACin_q >= DELTA_6_I else
140
                (others => '0');
141
 
142
  Next_Period           <= q(7 downto 0) - 1;
143
 
144
  vDSM_proc: process( Clock, Reset )
145
  begin
146
    if( Reset = Reset_Level )then
147
      q                 <= (others => '0');
148
      count             <= (others => '1');
149
      Divisor           <= (others => '0');
150
      DACin_q       <= (others => '0');
151
      PWM_Width         <= (others => '0');
152
      PWM_Period        <= (others => '0');
153
      Period_Ctr        <= (others => '0');
154
      Width_Ctr         <= (others => '0');
155
      DACout            <= '0';
156
    elsif( rising_edge(Clock) )then
157
      q                 <= diff(DIV_WIDTH-1 downto 0) &
158
                           q(DIV_WIDTH-2 downto 0) & '1';
159
      if( diff(DIV_WIDTH) = '1' )then
160
        q               <= q(DIV_WIDTH*2-2 downto 0) & '0';
161
      end if;
162
 
163
      count             <= count + 1;
164
      if( count = DIV_WIDTH )then
165
        PWM_Width       <= Next_Width;
166
        PWM_Period      <= Next_Period;
167
        DACin_q     <= DACin;
168
        Divisor         <= (others => '0');
169
        Divisor(DAC_Width-1 downto 0) <= DACin_q;
170
        q               <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
171
        count           <= (others => '0');
172
      end if;
173
 
174
      Period_Ctr        <= Period_Ctr - 1;
175
      Width_Ctr         <= Width_Ctr - 1;
176
 
177
      DACout            <= '1';
178
      if( Width_Ctr = 0 )then
179
        DACout          <= '0';
180
        Width_Ctr       <= (others => '0');
181
      end if;
182
 
183
      if( Period_Ctr = 0 )then
184
        Period_Ctr      <= PWM_Period;
185
        Width_Ctr       <= PWM_Width;
186
      end if;
187
 
188
    end if;
189
  end process;
190
 
191
end architecture;

powered by: WebSVN 2.1.0

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