VHDL Description*: Single-Tone Oscillator


* This code was prepared and tested by Benoit Veillette of McGill University.

----------------------------------------------------------------
- Single tone low pass oscillator core
-
- init1 Register 1 initial value
- init2 Register 2 initial value
- coef frequency setting coefficient
- clk main clock, circuit uses rising edge
- reset load registers with default values (asynchronous)
- sine pulse density modulated sine wave
- ow overflow error
----------------------------------------------------------------

entity single_tone_osc is
generic (bus_size: positive := 24);
port (init1,
init2,
coef: in bit_vector (bus_size-1 downto 0);
clk,
reset: in bit;
sine,
ow: out bit);
end single_tone_osc;

architecture structural of single_tone_osc is

component ds_2_lp
generic (ds_size: positive := 16);
port (wide: in bit_vector(ds_size-1 downto 0);
pdm: out bit;
clk: in bit;
reset: in bit;
ow: out bit);
end component;

component bv_flipflop_ad
generic (size: positive := 1);
port (value: out bit_vector(size-1 downto 0);
next_value: in bit_vector(size-1 downto 0);
default: in bit_vector(size-1 downto 0);
clk: in bit;
reset: in bit);
end component;

component coef_mux2
generic (size: positive := 16);
port (selector: in bit;
choice: out bit_vector(size-1 downto 0);
coef: in bit_vector(size-1 downto 0));
end component;

component adder
generic (size: positive := 16);
port (a, b: in bit_vector(size-1 downto 0);
x: out bit_vector(size-1 downto 0);
overflow: out bit);
end component;

-- Internal nets
signal mux_out,
reg2_in,
reg2_out,
reg1_in,
reg1_out: bit_vector(bus_size-1 downto 0);
signal ow_ds, ow_a1, ow_a2,
b_stream: bit;

begin
register1: bv_flipflop_ad
generic map (bus_size)
port map (reg1_out, reg1_in, init1, clk, reset);

modulator: ds_2_lp
generic map (bus_size)
port map (reg1_in, b_stream, clk, reset, ow_ds);

mult1: coef_mux2
generic map (bus_size)
port map (b_stream, mux_out, coef);

add1: adder
generic map (bus_size)
port map (mux_out, reg2_out, reg2_in, ow_a1);

register2: bv_flipflop_ad
generic map (bus_size)
port map (reg2_out, reg2_in, init2, clk, reset);

add2: adder
generic map (bus_size)
port map (reg2_in, reg1_out, reg1_in, ow_a2);

ow <= ow_ds or ow_a1 or ow_a2;

sine <= b_stream;

end structural;

---------------------------------------------------------------
-- Second order Low Pass delta-Sigma
--
-- wide modulator input
-- pdm single bit output
-- clk main clock, circuit uses rising edge
-- reset load registers with null value (asynchronous)
-- ow overflow error
---------------------------------------------------------------

library synopsys;
use synopsys.bv_arithmetic.all;

entity ds_2_lp is
generic (ds_size: positive :=1);
port (wide: in bit_vector(ds_size-1 downto 0);
pdm: out bit;
clk: in bit;
reset: in bit;
ow: out bit);
end ds_2_lp;

architecture structural of ds_2_lp is

component comp_ds
port (msb: in bit;
decision: out bit_vector(3 downto 0));
end component;

component bv_flipflop_ar
generic (size: positive := 1);
port (value: out bit_vector(size-1 downto 0);
next_value: in bit_vector(size-1 downto 0);
clk: in bit;
reset: in bit);
end component;

component adder
generic (size: positive := 16);
port (a, b: in bit_vector(size-1 downto 0);
x: out bit_vector(size-1 downto 0);
overflow: out bit);
end component;

signal feedback: bit_vector(ds_size+2 downto ds_size-1);
signal widex,
net1: bit_vector(ds_size downto ds_size-1);
signal net1x,
reg1_in,
reg1_out: bit_vector(ds_size+1 downto 0);
signal reg1_inx,
net2: bit_vector(ds_size+2 downto ds_size-1);
signal net2x,
reg2_in,
reg2_out: bit_vector(ds_size+3 downto 0);

signal ow2, ow4: bit;

begin
widex(ds_size-1) <= wide(ds_size-1);
widex(ds_size) <= wide(ds_size-1);

add1: adder
generic map (2)
port map (widex, feedback(ds_size downto ds_size-1),
net1,OPEN);

net1x (ds_size+1 downto ds_size-1) <= sxt(net1, 3);
net1x (ds_size-2 downto 0) <= wide(ds_size-2 downto 0);

add2: adder
generic map (ds_size+2)
port map (net1x, reg1_out, reg1_in, ow2);

reg1: bv_flipflop_ar
generic map (ds_size+2)
port map (reg1_out, reg1_in, clk, reset);

reg1_inx <= sxt(reg1_in(ds_size+1 downto ds_size-1), 4);

add3: adder
generic map (4)
port map (reg1_inx, feedback, net2, OPEN);

net2x(ds_size+3 downto ds_size-1) <= sxt(net2, 5);
net2x(ds_size-2 downto 0) <= reg1_in(ds_size-2 downto 0);

add4: adder
generic map (ds_size+4)
port map (net2x, reg2_out, reg2_in, ow4);

reg2: bv_flipflop_ar
generic map (ds_size+4)
port map (reg2_out, reg2_in, clk, reset);

comp: comp_ds
port map (reg2_out(ds_size+3), feedback);

pdm <= not feedback(ds_size+2);
ow <= ow2 or ow4;

end structural;

---------------------------------------------------------------
-- Special comparator for delta-sigma
---------------------------------------------------------------

library synopsys;
use synopsys.bv_arithmetic.all;

entity comp_ds is
port (msb: in bit;
decision: out bit_vector(3 downto 0));
end comp_ds;

architecture behavioural of comp_ds is
signal one: bit_vector(3 downto 0);
begin
one(3 downto 0) <= "0001";
process (msb, one)
begin
if msb = '1' then
decision <= one;
else
decision <= -one;
end if;
end process;
end behavioural;

---------------------------------------------------------------
-- Bit vector flip-flop with asynchronous default
---------------------------------------------------------------

entity bv_flipflop_ad is
generic (size: positive := 1);
port (value: out bit_vector(size-1 downto 0);
next_value: in bit_vector(size-1 downto 0);
default: in bit_vector(size-1 downto 0);
clk: in bit;
reset: in bit);
end bv_flipflop_ad;

architecture behavioural of bv_flipflop_ad is
begin
process (reset, clk, next_value, default)
begin
if (reset = '1') then
value <= default;
elsif (clk'event and clk = '1') then
value <= next_value;
end if;
end process;
end behavioural;

----------------------------------------------------------------
-- Bit vector flip-flop with asynchronous reset
----------------------------------------------------------------

library synopsys;
use synopsys.bv_arithmetic.all;

entity bv_flipflop_ar is
generic (size: positive := 1);
port (value: out bit_vector(size-1 downto 0);
next_value: in bit_vector(size-1 downto 0);
clk: in bit;
reset: in bit);
end bv_flipflop_ar;

architecture behavioural of bv_flipflop_ar is
begin
process (reset, clk, next_value)
begin
if (reset = '1') then
value <= sxt("0", size);
elsif (clk'event and clk = '1') then
value <= next_value;
end if;
end process;
end behavioural;

----------------------------------------------------------------
-- Adder
----------------------------------------------------------------

library synopsys;
use synopsys.bv_arithmetic.all;

entity adder is
generic (size: positive := 1);
port (a, b: in bit_vector(size-1 downto 0);
x: out bit_vector(size-1 downto 0);
overflow: out bit);
end adder;

architecture behavioural of adder is
begin
process (a, b)
variable y: bit_vector(size-1 downto 0);
variable owp, own: bit;
begin
y := (a + b);
x <= y;
own := a(size-1) and b(size-1) and not y(size-1);
owp := not a(size-1) and not b(size-1) and y(size-1);
overflow <= own or owp;
end process;
end behavioural;

----------------------------------------------------------------
-- Coefficient multiplexer 2x1
----------------------------------------------------------------

library synopsys;
use synopsys.bv_arithmetic.all;

entity coef_mux2 is
generic (size: positive := 1);
port (selector: in bit;
choice: out bit_vector(size-1 downto 0);
coef: in bit_vector(size-1 downto 0));
end coef_mux2;

architecture behavioural of coef_mux2 is
begin
process (selector, coef)
begin
if selector = '1' then
choice <= coef;
else
choice <= -coef;
end if;
end process;
end behavioural;