summaryrefslogtreecommitdiff
path: root/testsuite/gna/bug17309/polyamplib.vhdl
diff options
context:
space:
mode:
authorTristan Gingold2014-01-01 08:30:17 +0100
committerTristan Gingold2014-01-01 08:30:17 +0100
commit876d38444585710c6e9cbe609a56f907d963842f (patch)
tree8f6b8d7c510764007aeb54937f60ef8394e4cfdf /testsuite/gna/bug17309/polyamplib.vhdl
parent98ef692fe333e01f4e7127e6dee719b1aa7621b5 (diff)
downloadghdl-876d38444585710c6e9cbe609a56f907d963842f.tar.gz
ghdl-876d38444585710c6e9cbe609a56f907d963842f.tar.bz2
ghdl-876d38444585710c6e9cbe609a56f907d963842f.zip
Add bug17309
Diffstat (limited to 'testsuite/gna/bug17309/polyamplib.vhdl')
-rw-r--r--testsuite/gna/bug17309/polyamplib.vhdl1860
1 files changed, 1860 insertions, 0 deletions
diff --git a/testsuite/gna/bug17309/polyamplib.vhdl b/testsuite/gna/bug17309/polyamplib.vhdl
new file mode 100644
index 0000000..4793cd5
--- /dev/null
+++ b/testsuite/gna/bug17309/polyamplib.vhdl
@@ -0,0 +1,1860 @@
+-----------------------------------------------------------------------------
+-- Polyamp vhdl function library
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package polyamplib is
+
+ component interface_ads1271
+ port (
+ fastclk : in std_logic; -- Fast clock
+ adclk : in std_logic; -- A/D converter clock
+ resync : in std_logic; -- Clock change; resync
+ ser_data : in std_logic; -- Serial data in
+ n_drdy : in std_logic; -- Data is ready, active low
+ data_out : out std_logic_vector(23 downto 0); -- Parallell data out
+ nsync : out std_logic; -- Synchronize (restart) A/D conv.
+ busy : out std_logic; -- Busy reading serial data
+ g_sclk : out std_logic); -- Gated SPI clock, FOR SIMULATION ONLY
+ end component;
+
+ component priority_resolver2 is
+ port (
+ inp : in std_logic_vector(11 downto 0);
+ prio : out unsigned(3 downto 0); -- Output highest signal
+ active : out std_logic); -- High when any input is active
+ end component;
+
+ component one_of_n_encoder is
+ port (
+ number : in unsigned(3 downto 0);
+ enable : in std_logic;
+ single_out : out std_logic_vector(11 downto 0)); -- Only a single wire is active at a time
+ end component;
+
+ component active_input is
+ port (
+ fastclk : in std_logic; -- Main clock
+ enable : in std_logic; -- Enable signal
+ busy_n : in std_logic; -- Busy input signal, active low
+ clear : in std_logic; -- Clear the corresponding flip-flop
+ active_out : out std_logic); -- Active output
+ end component;
+
+ component master_state_machine is
+ port (
+ fastclk : in std_logic := '0'; -- Main clock
+ enable_lo8 : in std_logic; -- Enable the 8 low inputs
+ busy_n_vec : in std_logic_vector(11 downto 0); -- Busy inputs
+ id_code : inout unsigned(3 downto 0); -- Id code output
+ fifo_write : out std_logic); -- Save to fifo
+ end component;
+
+ component fifo_memory is
+ generic (
+ fifo_size : natural := 100);
+ port (
+ clock : in std_logic;
+ sclr : in std_logic;
+ datain : in std_logic_vector(31 downto 0);
+ wrreq : in std_logic;
+ rdreq : in std_logic;
+ dataout : out std_logic_vector(31 downto 0);
+ full : out std_logic;
+ empty : out std_logic;
+ meter : out unsigned(7 downto 0));
+ end component;
+
+ component fifo_ft_memory is
+ generic (
+ fifo_size : natural := 100);
+ port (
+ clock : in std_logic;
+ sclr : in std_logic;
+ datain : in std_logic_vector(31 downto 0);
+ wrreq : in std_logic;
+ rdreq : in std_logic;
+ dataout : out std_logic_vector(31 downto 0);
+ full : out std_logic;
+ empty : out std_logic;
+ meter : out unsigned(7 downto 0));
+ end component;
+
+ component ads1271_model is
+ port (
+ analog_in : in signed(23 downto 0); -- Analog input signal
+ clk : in std_logic; -- Conversion clock
+ sclk : in std_logic; -- SPI clock
+ n_sync : in std_logic; -- Input sync signal, active low
+ din : in std_logic; -- Serial data in
+ dout : out std_logic; -- Serial data out
+ n_drdy : out std_logic); -- Data ready, active low
+ end component;
+
+ component sr_sipo is
+ generic (
+ LENGTH : positive := 8; --! Shift register length
+ EDGE : natural := 1; --! Active edge; 1=positive, 0=negative
+ DIR : natural := 1); --! Direction; 1=left, 0=right
+ port (
+ clk : in std_logic; --! Clock input
+ ser_in : in std_logic; --! Serial input data
+ par_out : out std_logic_vector(1 to LENGTH)); --! Parallel output data
+ end component;
+
+ component sr_piso is
+ generic (
+ LENGTH : positive := 8; --! Shift register length
+ EDGE : natural := 1; --! Active edge; 1=positive, 0=negative
+ DIR : natural := 1); --! Direction; 1=left, 0=right
+ port (
+ clk : in std_logic; --! Clock input
+ load : in std_logic; --! Load on next clock
+ par_in : in std_logic_vector(1 to LENGTH); --! Parallel input data
+ ser_in : in std_logic; --! Serial input data
+ ser_out : out std_logic); --! Serial output data
+ end component;
+
+ component sr_piso_s is
+ generic (
+ LENGTH : positive := 8; --! Shift register length
+ DIR : natural := 1); --! Direction; 1=left, 0=right
+ port (
+ fastclk : in std_logic; --! Synchronous clock
+ clk_en : in std_logic; --! Clock enable input
+ load_en : in std_logic; --! Load enable input
+ par_in : in std_logic_vector(1 to LENGTH); --! Parallel input data
+ ser_in : in std_logic; --! Serial input data
+ ser_out : out std_logic); --! Serial output data
+ end component;
+
+ component spi_slave is
+ port (
+ -- Main controls
+ fastclk : in std_logic;
+ spi_tx : in std_logic_vector(31 downto 0); -- Data to be sent
+ spi_rx : out std_logic_vector(31 downto 0); -- Data to be received
+ spi_op : out std_logic; -- Read/Write status/data/command
+
+ -- Slave port, connected to CPU
+ mosi : in std_logic;
+ miso : out std_logic;
+ sck : in std_logic; -- SPI clock
+ en_adc : in std_logic; -- Active low, enable ADC
+ en_incl : in std_logic; -- Active low, enable inclinometer
+
+ -- Master port, connected to inclinometer
+ incl_miso : in std_logic;
+ incl_mosi : out std_logic;
+ incl_sck : out std_logic;
+ incl_ena : out std_logic); -- Active low, enable inclinometer
+ end component;
+
+ component command_decoder is
+ port (
+ addr_data : in std_logic_vector(31 downto 0); -- Input address/data
+ decode : in std_logic; -- Single cycle decode pulse
+ fastclk : in std_logic; -- Master clock (not used for now)
+ sel_nulcmd : out std_logic; -- NULL command (no operation)
+ sel_adclk0 : out std_logic; -- Select sampling clock, ad0.
+ sel_adclk1 : out std_logic; -- Select sampling clock, ad1.
+ sel_adclk2 : out std_logic; -- Select sampling clock, ad2.
+ sel_adclk3 : out std_logic; -- Select sampling clock, ad3.
+ sel_adclk4 : out std_logic; -- Select sampling clock, ad4.
+ sel_adclk5 : out std_logic; -- Select sampling clock, ad5.
+ sel_adclk6 : out std_logic; -- Select sampling clock, ad6.
+ sel_adclk7 : out std_logic; -- Select sampling clock, ad7.
+ resync_adc : out std_logic; -- Resynchronize all ADC's
+ write_ctrl : out std_logic; -- Write to control-signal register
+ start_adcs : out std_logic; -- Start AD-conversion
+ stop_adcs : out std_logic); -- Stop AD-conversion
+ end component;
+
+ component clockmux is
+ port (
+ clk24M : in std_logic; -- Input clocks, 24 576 000
+ clk4M : in std_logic; -- 4 096 000
+ clk2M : in std_logic; -- 2 048 000
+ clk1M : in std_logic; -- 1 024 000
+ clk512k : in std_logic; -- 512 000
+ clk256k : in std_logic; -- 256 000
+ clk128k : in std_logic; -- 128 000
+ sel : in unsigned(2 downto 0); -- Mux select input
+ clkout : out std_logic); -- Output clock
+ end component;
+
+ component spi_master is
+ port (
+ -- Hardware ports
+ miso : in std_logic;
+ mosi : out std_logic;
+ sck : inout std_logic;
+ en_adval : out std_logic := '1';
+ en_incl : out std_logic := '1';
+
+ -- Simulation ports
+ data_to_spi : in std_logic_vector(31 downto 0);
+ data_from_spi : out std_logic_vector(31 downto 0);
+ start : in std_logic;
+ busy : out std_logic := '0';
+ running : in std_logic);
+ end component;
+
+ component spi_slave_burst is
+ port (
+ -- Main controls
+ fastclk : in std_logic;
+ spi_tx : in std_logic_vector(31 downto 0); -- Data to be sent
+ spi_rx : out std_logic_vector(31 downto 0); -- Data to be received
+ exec_cmd : out std_logic; -- Write command/data
+ fifo_read : out std_logic; -- Read status/data
+
+ -- Slave port, connected to CPU
+ mosi : in std_logic;
+ miso : out std_logic;
+ sck : in std_logic; -- SPI clock
+ en_adc : in std_logic; -- Active low, enable ADC
+ en_incl : in std_logic; -- Active low, enable inclinometer
+
+ -- Master port, connected to inclinometer
+ incl_miso : in std_logic;
+ incl_mosi : out std_logic;
+ incl_sck : out std_logic;
+ incl_ena : out std_logic); -- Active low, enable inclinometer
+ end component;
+
+ component sync_logic_2 is
+ port (
+ start_adcs : in std_logic; -- Start command
+ stop_adcs : in std_logic; -- Stop command
+ reset : in std_logic; -- Active high
+ hwsync : in std_logic; -- Hardware sync
+ fastclk : in std_logic; -- Master clock
+ enable_adcvalues : out std_logic); -- Enable reception of values
+ end component;
+
+end polyamplib;
+
+
+-----------------------------------------------------------------------------
+-- Shift register for adc_interface, spi_interface etc.
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+--! General serial input, parallell output shift register
+
+--! The shift register length is generic, from 2 and up. It can trigger on
+--! positive or negative edges, and the shift direction can be choosen as well.
+entity sr_sipo is
+ generic (
+ LENGTH : positive := 8; --! Shift register length
+ EDGE : natural := 1; --! Active edge; 1=positive, 0=negative
+ DIR : natural := 1); --! Direction; 1=left, 0=right
+ port (
+ clk : in std_logic; --! Clock input
+ ser_in : in std_logic; --! Serial input data
+ par_out : out std_logic_vector(1 to LENGTH)); --! Parallel output data
+end sr_sipo;
+
+architecture sr_arch of sr_sipo is
+
+ signal my_sr : std_logic_vector(1 to LENGTH);
+
+begin -- sr_arch
+
+ posedge_right : if (EDGE = 1) and (DIR = 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '1' then -- Positive clock edge
+ my_sr(1 to LENGTH) <= (my_sr(2 to LENGTH) & ser_in);
+ end if;
+ end process shift;
+ end generate posedge_right;
+
+ posedge_left : if (EDGE = 1) and (DIR /= 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '1' then -- Positive clock edge
+ my_sr(1 to LENGTH) <= (ser_in & my_sr(1 to LENGTH-1));
+ end if;
+ end process shift;
+ end generate posedge_left;
+
+ negedge_right : if (EDGE /= 1) and (DIR = 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '0' then -- Negative clock edge
+ my_sr(1 to LENGTH) <= (my_sr(2 to LENGTH) & ser_in);
+ end if;
+ end process shift;
+ end generate negedge_right;
+
+ negedge_left : if (EDGE /= 1) and (DIR /= 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '0' then -- Negative clock edge
+ my_sr(1 to LENGTH) <= (ser_in & my_sr(1 to LENGTH-1));
+ end if;
+ end process shift;
+ end generate negedge_left;
+
+ par_out <= my_sr(1 to LENGTH) after 2 ns;
+
+end sr_arch;
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- Shift register for spi_interface
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+--! General parallell input, serial output shift register
+
+--! The shift register length is generic, from 2 and up. It can trigger on
+--! positive or negative edges, and the shift direction can be choosen as well.
+
+entity sr_piso is
+ generic (
+ LENGTH : positive := 8; --! Shift register length
+ EDGE : natural := 1; --! Active edge; 1=positive, 0=negative
+ DIR : natural := 1); --! Direction; 1=left, 0=right
+ port (
+ clk : in std_logic; --! Clock input
+ load : in std_logic; --! Load on next clock
+ par_in : in std_logic_vector(1 to LENGTH); --! Parallel input data
+ ser_in : in std_logic; --! Serial input data
+ ser_out : out std_logic); --! Serial output data
+end sr_piso;
+
+architecture sr_arch of sr_piso is
+
+ signal my_sr : std_logic_vector(1 to LENGTH);
+
+begin -- sr_arch
+
+ shift_left : if DIR = 1 generate
+ ser_out <= my_sr(1) after 2 ns;
+ end generate shift_left;
+
+ shift_right : if DIR /= 1 generate
+ ser_out <= my_sr(LENGTH) after 2 ns;
+ end generate shift_right;
+
+ posedge_left : if (EDGE = 1) and (DIR = 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '1' then -- Positive clock edge
+ if load = '1' then
+ my_sr <= par_in;
+ else
+ my_sr(1 to (LENGTH-1)) <= my_sr(2 to LENGTH);
+ my_sr(LENGTH) <= ser_in;
+ end if;
+ end if;
+ end process shift;
+ end generate posedge_left;
+
+ posedge_right : if (EDGE = 1) and (DIR /= 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '1' then -- Positive clock edge
+ if load = '1' then
+ my_sr <= par_in;
+ else
+ my_sr(2 to LENGTH) <= my_sr(1 to LENGTH-1);
+ my_sr(1) <= ser_in;
+ end if;
+ end if;
+ end process shift;
+ end generate posedge_right;
+
+ negedge_left : if (EDGE /= 1) and (DIR = 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '0' then -- Negative clock edge
+ if load = '1' then
+ my_sr <= par_in;
+ else
+ my_sr(1 to (LENGTH-1)) <= my_sr(2 to LENGTH);
+ my_sr(LENGTH) <= ser_in;
+ end if;
+ end if;
+ end process shift;
+ end generate negedge_left;
+
+ negedge_right : if (EDGE /= 1) and (DIR /= 1) generate
+ shift : process(clk)
+
+ begin
+ if clk'event and clk = '0' then -- Negative clock edge
+ if load = '1' then
+ my_sr <= par_in;
+ else
+ my_sr(2 to LENGTH) <= my_sr(1 to LENGTH-1);
+ my_sr(1) <= ser_in;
+ end if;
+ end if;
+ end process shift;
+ end generate negedge_right;
+
+end sr_arch;
+
+
+
+
+-----------------------------------------------------------------------------
+-- Synchronously clocked shift register for spi_interface
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+--! Synchronously clocked parallell input, serial output shift register
+
+--! The shift register length is generic, from 2 and up.
+--! The shift direction can be choosen.
+
+entity sr_piso_s is
+ generic (
+ LENGTH : positive := 8; --! Shift register length
+ DIR : natural := 1); --! Direction; 1=left, 0=right
+ port (
+ fastclk : in std_logic; --! Synchronous clock
+ clk_en : in std_logic; --! Clock enable input
+ load_en : in std_logic; --! Load enable input
+ par_in : in std_logic_vector(1 to LENGTH); --! Parallel input data
+ ser_in : in std_logic; --! Serial input data
+ ser_out : out std_logic); --! Serial output data
+end sr_piso_s;
+
+
+architecture ar_piso_s_arch of sr_piso_s is
+
+ signal my_sr : std_logic_vector(1 to LENGTH);
+
+begin -- ar_piso_s_arch
+
+ shift_left_out : if DIR = 1 generate
+ ser_out <= my_sr(1) after 2 ns;
+ end generate shift_left_out;
+
+ shift_right_out : if DIR /= 1 generate
+ ser_out <= my_sr(LENGTH) after 2 ns;
+ end generate shift_right_out;
+
+ shift_left : if (DIR = 1) generate
+ shift : process(fastclk)
+
+ begin
+ if rising_edge(fastclk) then -- Positive clock edge
+ if load_en = '1' then
+ my_sr <= par_in;
+ elsif clk_en = '1' then
+ my_sr(1 to (LENGTH-1)) <= my_sr(2 to LENGTH);
+ my_sr(LENGTH) <= ser_in;
+ end if;
+ end if;
+ end process shift;
+ end generate shift_left;
+
+ shift_right : if (DIR /= 1) generate
+ shift : process(fastclk)
+
+ begin
+ if rising_edge(fastclk) then -- Positive clock edge
+ if load_en = '1' then
+ my_sr <= par_in;
+ elsif clk_en = '1' then
+ my_sr(2 to LENGTH) <= my_sr(1 to LENGTH-1);
+ my_sr(1) <= ser_in;
+ end if;
+ end if;
+ end process shift;
+ end generate shift_right;
+
+
+end ar_piso_s_arch;
+
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- The adc_interface
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity interface_ads1271 is
+
+ port (
+ fastclk : in std_logic; -- Fast clock
+ adclk : in std_logic; -- A/D converter clock
+ resync : in std_logic; -- Clock change; resync
+ ser_data : in std_logic; -- Serial data in
+ n_drdy : in std_logic; -- Data is ready, active low
+ data_out : out std_logic_vector(23 downto 0); -- Parallell data out
+ nsync : out std_logic := '1'; -- Synchronize (restart) A/D conv.
+ busy : out std_logic; -- Busy reading serial data
+ g_sclk : out std_logic); -- Gated SPI clock, FOR SIMULATION ONLY
+
+end interface_ads1271;
+
+
+architecture interface_ads1271_arch of interface_ads1271 is
+
+ type state_type is (idle, counting, freeze);
+ signal state : state_type := idle; -- Controlling state machine
+ signal unlatch_data : std_logic_vector(23 downto 0) := (others => '0'); -- From shift register
+ signal bitcounter : unsigned(4 downto 0) := to_unsigned(0, 5); -- Range 0..31
+ signal g_sclk_enable : std_logic := '0';
+
+ type rsync_sm_type is (rs_idle, rs_clo1, rs_chi, rs_clo2);
+ signal rsync_sm : rsync_sm_type := rs_idle;
+
+ component sr_sipo is
+ generic (
+ LENGTH : positive; --! Shift register length
+ EDGE : natural; --! Active edge; 1=positive, 0=negative
+ DIR : natural); --! Direction; 1=left, 0=right
+ port (
+ clk : in std_logic; --! Clock input
+ ser_in : in std_logic; --! Serial input data
+ par_out : out std_logic_vector(1 to LENGTH)); --! Parallel output data
+ end component;
+
+
+begin -- interface_ads1271_arch
+
+ sr1 : sr_sipo generic map (
+ LENGTH => 24,
+ EDGE => 1,
+ DIR => 1)
+ port map (
+ clk => adclk,
+ ser_in => ser_data,
+ par_out => unlatch_data);
+
+
+-- Static interconnects
+ g_sclk <= g_sclk_enable and adclk;
+
+
+
+-- purpose: Freeze output data
+-- type : sequential
+-- inputs : adclk, n_drdy
+
+ freeze_proc : process (adclk)
+ begin -- process freeze_proc
+ if rising_edge(adclk) then -- rising clock edge
+ case state is
+ when idle => if n_drdy = '0' then
+ busy <= '1';
+ state <= counting;
+ bitcounter <= to_unsigned(23, 5);
+ g_sclk_enable <= '1';
+ else
+ busy <= '0';
+ end if;
+ when counting => busy <= '1';
+ if bitcounter > 0 then
+ bitcounter <= bitcounter - 1;
+ else
+ state <= freeze;
+ data_out <= unlatch_data;
+ g_sclk_enable <= '0';
+ end if;
+ when freeze => busy <= '0';
+ if n_drdy = '1' then
+ state <= idle;
+ end if;
+ when others => state <= idle; busy <= '0';
+ end case;
+ end if;
+ end process freeze_proc;
+
+
+
+-- purpose: Handle resyncronization of A/D converters
+-- Keep nsync low for at least one adclk cycle
+-- type : sequential
+-- inputs : fastclk, adclk, resync
+-- outputs: nsync
+ resync_proc : process (fastclk)
+ begin -- process resync_proc
+ if rising_edge(fastclk) then -- rising clock edge
+ nsync <= '0';
+ case rsync_sm is
+ when rs_idle => if resync = '1' then
+ rsync_sm <= rs_clo1;
+ else
+ nsync <= '1';
+ end if;
+ when rs_clo1 => if adclk = '0' then
+ rsync_sm <= rs_chi;
+ end if;
+ when rs_chi => if adclk = '1' then
+ rsync_sm <= rs_clo2;
+ end if;
+ when rs_clo2 => if adclk = '0' then
+ rsync_sm <= rs_idle;
+ end if;
+ when others => rsync_sm <= rs_idle;
+ nsync <= '1';
+ end case;
+end if;
+end process resync_proc;
+
+end interface_ads1271_arch;
+
+
+
+
+-----------------------------------------------------------------------------
+-- The priority_resolver2
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity priority_resolver2 is
+ port (
+ inp : in std_logic_vector(11 downto 0); -- Active low inputs
+ prio : out unsigned(3 downto 0); -- Output highest signal
+ active : out std_logic); -- High when any input is active
+end priority_resolver2;
+
+
+architecture priority_resolver2_arch of priority_resolver2 is
+
+begin -- priority_resolver2_arch
+
+ -- Any input active ???
+ active <= inp(0) or inp(1) or inp(2) or inp(3) or inp(4) or inp(5) or
+ inp(6) or inp(7) or inp(8) or inp(9) or inp(10) or inp(11) after 1 ns;
+
+ -- purpose: Priority resolver
+ -- type : combinational
+ -- inputs : inp
+ -- outputs: prio, active
+ mainloop : process (inp)
+ begin -- process mainloop
+ if inp(11) = '1' then
+ prio <= to_unsigned(11, 4) after 1 ns;
+ elsif inp(10) = '1' then
+ prio <= to_unsigned(10, 4) after 1 ns;
+ elsif inp(9) = '1' then
+ prio <= to_unsigned(9, 4) after 1 ns;
+ elsif inp(8) = '1' then
+ prio <= to_unsigned(8, 4) after 1 ns;
+ elsif inp(7) = '1' then
+ prio <= to_unsigned(7, 4) after 1 ns;
+ elsif inp(6) = '1' then
+ prio <= to_unsigned(6, 4) after 1 ns;
+ elsif inp(5) = '1' then
+ prio <= to_unsigned(5, 4) after 1 ns;
+ elsif inp(4) = '1' then
+ prio <= to_unsigned(4, 4) after 1 ns;
+ elsif inp(3) = '1' then
+ prio <= to_unsigned(3, 4) after 1 ns;
+ elsif inp(2) = '1' then
+ prio <= to_unsigned(2, 4) after 1 ns;
+ elsif inp(1) = '1' then
+ prio <= to_unsigned(1, 4) after 1 ns;
+ else
+ prio <= to_unsigned(0, 4) after 1 ns;
+ end if;
+ end process mainloop;
+
+end priority_resolver2_arch;
+
+
+
+
+-----------------------------------------------------------------------------
+-- The active_input state machine
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity active_input is
+ port (
+ fastclk : in std_logic; -- Main clock
+ enable : in std_logic; -- Enable signal
+ busy_n : in std_logic; -- Busy input signal, active low
+ clear : in std_logic; -- Clear the corresponding flip-flop
+ active_out : out std_logic); -- Active output
+end active_input;
+
+
+architecture active_input_arch of active_input is
+
+ type input_state_type is (i_idle, i_active, i_decay);
+ signal i_state : input_state_type := i_idle;
+ signal temp_active_out : std_logic := '0'; -- Temporary signal'
+
+
+begin -- active_input_arch
+
+ -- Static delayed connex
+ active_out <= temp_active_out after 1 ns;
+
+
+ -- purpose: Input state machine
+ -- type : sequential
+ -- inputs : fastclk, fastclk, busy_n, clear
+ -- outputs: temp_active_out
+ input_active : process (fastclk)
+
+ begin -- process input_active
+ if rising_edge(fastclk) then -- rising clock edge
+ temp_active_out <= '0';
+ case i_state is
+ when i_idle => if (busy_n = '0') and (enable = '1') then
+ temp_active_out <= '1';
+ i_state <= i_active;
+ end if;
+
+ when i_active => if clear = '0' then
+ temp_active_out <= '1';
+ else
+ i_state <= i_decay;
+ end if;
+
+ when i_decay => if busy_n = '1' then
+ i_state <= i_idle;
+ end if;
+
+ when others => i_state <= i_idle;
+ end case;
+
+ end if;
+ end process input_active;
+end active_input_arch;
+
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- The one_of_n_encoder
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity one_of_n_encoder is
+
+ port (
+ number : in unsigned(3 downto 0);
+ enable : in std_logic;
+ single_out : out std_logic_vector(11 downto 0)); -- Only a single wire is active at a time
+
+end one_of_n_encoder;
+
+
+
+architecture one_of_n_encoder_arch of one_of_n_encoder is
+
+ type out_table_type is array (0 to 15) of std_logic_vector(11 downto 0);
+ constant out_table : out_table_type :=
+ ("000000000001",
+ "000000000010",
+ "000000000100",
+ "000000001000",
+ "000000010000",
+ "000000100000",
+ "000001000000",
+ "000010000000",
+ "000100000000",
+ "001000000000",
+ "010000000000",
+ "100000000000",
+ "000000000000",
+ "000000000000",
+ "000000000000",
+ "000000000000");
+
+begin -- one_of_n_encoder_arch
+
+ -- purpose: Translate unsigned number into a signle output
+ -- type : sequential
+ -- inputs : number, number, enable
+ -- outputs: single_out
+ xlate : process (number, enable)
+ begin -- process xlate
+ if enable = '1' then
+ single_out <= out_table(to_integer(number)) after 1 ns;
+ else
+ single_out <= "000000000000" after 1 ns;
+ end if;
+
+ end process xlate;
+
+end one_of_n_encoder_arch;
+
+
+
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- The master_state_machine
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.polyamplib.all;
+
+entity master_state_machine is
+
+ port (
+
+ fastclk : in std_logic := '0'; -- Main clock
+ enable_lo8 : in std_logic; -- Enable the 8 low inputs
+ busy_n_vec : in std_logic_vector(11 downto 0); -- Busy inputs
+ id_code : inout unsigned(3 downto 0); -- Id code output
+ fifo_write : out std_logic); -- Save to fifo
+
+end master_state_machine;
+
+
+
+architecture master_state_machine_arch of master_state_machine is
+
+ signal active_data : std_logic_vector(11 downto 0);
+ signal clear_vec : std_logic_vector(11 downto 0);
+ signal any_active : std_logic := '0'; -- Is any input active ???
+ signal clear_enable : std_logic := '0'; -- Clear the current active input flip-flop
+ signal temp_clear_en : std_logic := '0';
+ signal priority : unsigned(3 downto 0);
+
+ type master_state_type is (m_idle, m_latch, m_clear, m_decay);
+ signal m_state : master_state_type := m_idle;
+
+
+
+begin -- master_state_machine_arch
+
+ -- The first 8 are controlled by the enable_lo8 signal
+ gen1 : for i in 0 to 7 generate
+ inp_sm : active_input port map (
+ fastclk => fastclk,
+ enable => enable_lo8,
+ busy_n => busy_n_vec(i),
+ clear => clear_vec(i),
+ active_out => active_data(i));
+ end generate gen1;
+
+ -- The other inputs are always enabled
+ gen2 : for i in 8 to 11 generate
+ inp_sm : active_input port map (
+ fastclk => fastclk,
+ enable => '1',
+ busy_n => busy_n_vec(i),
+ clear => clear_vec(i),
+ active_out => active_data(i));
+ end generate gen2;
+
+ resolve : priority_resolver2 port map (
+ inp => active_data,
+ prio => priority,
+ active => any_active);
+
+ encode : one_of_n_encoder port map (
+ number => id_code,
+ enable => clear_enable,
+ single_out => clear_vec);
+
+
+ clear_enable <= temp_clear_en after 1 ns; -- After some delay
+ fifo_write <= clear_enable; -- Same-same
+
+
+ -- purpose: Master state machine
+ -- type : sequential
+ -- inputs : fastclk, s0..s11,c0..c11
+ -- outputs: fifo_write, data_id
+ master_loop : process (fastclk)
+
+ begin -- process master_loop
+
+ if rising_edge(fastclk) then -- rising clock edge
+ temp_clear_en <= '0';
+ case m_state is
+ when m_idle => if any_active = '1' then
+ id_code <= priority after 1 ns;
+ m_state <= m_latch;
+ end if;
+
+ when m_latch =>
+ temp_clear_en <= '1';
+ m_state <= m_clear;
+
+ when m_clear =>
+ m_state <= m_decay;
+
+ when m_decay =>
+ if any_active = '1' then
+ id_code <= priority after 1 ns;
+ m_state <= m_latch;
+ else
+ m_state <= m_idle;
+ end if;
+
+ when others => m_state <= m_idle;
+ end case;
+ end if;
+
+ end process master_loop;
+
+end master_state_machine_arch;
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- The fifo_memory
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+--use work.polyamplib.all;
+
+entity fifo_memory is
+ generic (
+ fifo_size : natural := 100);
+ port (
+ clock : in std_logic;
+ sclr : in std_logic;
+ datain : in std_logic_vector(31 downto 0);
+ wrreq : in std_logic;
+ rdreq : in std_logic;
+ dataout : out std_logic_vector(31 downto 0);
+ full : out std_logic;
+ empty : out std_logic;
+ meter : out unsigned(7 downto 0));
+end fifo_memory;
+
+
+
+architecture fifo_memory_arch of fifo_memory is
+
+begin -- fifo_memory_arch
+
+ -- purpose: Fifo memory simulator
+ -- type : sequential
+ -- inputs : clock, datain, wrreq, rdreq, clock
+ -- outputs: dataout, full, empty
+ fifo_mem : process (clock)
+
+ subtype word is std_logic_vector(31 downto 0);
+ type memory_area is array(0 to fifo_size) of word;
+ variable fifo : memory_area; -- The fifo memory area
+
+ variable head_ix : natural := 0; -- Write data to this address
+ variable tail_ix : natural := 0; -- Read data from this address
+ variable test_ix : natural := 0; -- Used for test of overflow/underflow
+
+ begin -- process fifo
+ if rising_edge(clock) then -- rising clock edge
+
+ -- Synchronous clear
+ if sclr = '1' then
+ head_ix := 0;
+ tail_ix := 0;
+ elsif wrreq = '1' then -- Fifo write op's
+ test_ix := head_ix + 1;
+ if test_ix > fifo_size then
+ test_ix := 0;
+ end if;
+ -- Writing to full fifo discards the last value
+ if test_ix /= tail_ix then -- NOT full
+ fifo(head_ix) := datain; -- Write data
+ head_ix := test_ix; -- And adjust the pointer
+ end if;
+ end if;
+
+ -- Reading empty fifo returns the last value
+ if (rdreq = '1') and (head_ix /= tail_ix) then
+ dataout <= fifo(tail_ix) after 1 ns;
+ tail_ix := tail_ix + 1;
+ if tail_ix > fifo_size then
+ tail_ix := 0;
+ end if;
+ end if;
+
+ -- Fifo empty signal
+ if head_ix = tail_ix then
+ empty <= '1' after 1 ns;
+ else
+ empty <= '0' after 1 ns;
+ end if;
+
+ -- Fifo full signal
+ if (tail_ix = (head_ix+1)) or ((tail_ix = 0) and (head_ix = fifo_size)) then
+ full <= '1' after 1 ns;
+ else
+ full <= '0' after 1 ns;
+ end if;
+
+ -- Fifo fill meter operations
+ if head_ix >= tail_ix then
+ meter <= to_unsigned(head_ix - tail_ix, 8);
+ else
+ meter <= to_unsigned(fifo_size + 1 + head_ix - tail_ix, 8);
+ end if;
+
+ end if;
+ end process fifo_mem;
+
+end fifo_memory_arch;
+
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- The fifo_ft_memory
+-----------------------------------------------------------------------------
+
+-- Fallthrough fifo memory model
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+--use work.polyamplib.all;
+
+entity fifo_ft_memory is
+ generic (
+ fifo_size : natural := 100);
+ port (
+ clock : in std_logic;
+ sclr : in std_logic;
+ datain : in std_logic_vector(31 downto 0);
+ wrreq : in std_logic;
+ rdreq : in std_logic;
+ dataout : out std_logic_vector(31 downto 0);
+ full : out std_logic;
+ empty : out std_logic;
+ meter : out unsigned(7 downto 0));
+end fifo_ft_memory;
+
+
+
+architecture fifo_ft_memory_arch of fifo_ft_memory is
+
+begin -- fifo_ft_memory_arch
+
+ -- purpose: Fifo memory simulator
+ -- type : sequential
+ -- inputs : clock, datain, wrreq, rdreq, clock
+ -- outputs: dataout, full, empty
+ fifo_mem : process (clock)
+
+ subtype word is std_logic_vector(31 downto 0);
+ type memory_area is array(0 to fifo_size) of word;
+ variable fifo : memory_area; -- The fifo memory area
+
+ variable head_ix : natural := 0; -- Write data to this address
+ variable tail_ix : natural := 0; -- Read data from this address
+ variable test_ix : natural := 0; -- Used for test of overflow/underflow
+
+ begin -- process fifo
+ if rising_edge(clock) then -- rising clock edge
+
+ -- Synchronous clear
+ if sclr = '1' then
+ head_ix := 0;
+ tail_ix := 0;
+ else
+ -- Write to fifo
+ if wrreq = '1' then -- Fifo write op's
+ test_ix := head_ix + 1;
+ if test_ix > fifo_size then
+ test_ix := 0;
+ end if;
+
+ -- Fifo is empty
+ if head_ix = tail_ix then
+ dataout <= datain; -- Let data fall-through
+ fifo(head_ix) := datain; -- Write data
+ head_ix := test_ix; -- And adjust the pointer
+ elsif test_ix /= tail_ix then -- NOT full
+ fifo(head_ix) := datain; -- Write data
+ head_ix := test_ix; -- And adjust the pointer
+ end if;
+ end if;
+
+ -- Reading empty fifo returns the last value
+ if (rdreq = '1') and (head_ix /= tail_ix) then
+ tail_ix := tail_ix + 1;
+ if tail_ix > fifo_size then
+ tail_ix := 0;
+ end if;
+ if tail_ix /= head_ix then
+ dataout <= fifo(tail_ix) after 1 ns;
+ end if;
+ end if;
+ end if;
+
+
+ -- Fifo empty signal
+ if head_ix = tail_ix then
+ empty <= '1' after 1 ns;
+ else
+ empty <= '0' after 1 ns;
+ end if;
+
+ -- Fifo full signal
+ if (tail_ix = (head_ix+1)) or ((tail_ix = 0) and (head_ix = fifo_size)) then
+ full <= '1' after 1 ns;
+ else
+ full <= '0' after 1 ns;
+ end if;
+
+ -- Fifo fill meter operations
+ if head_ix >= tail_ix then
+ meter <= to_unsigned(head_ix - tail_ix, 8);
+ else
+ meter <= to_unsigned(fifo_size + 1 + head_ix - tail_ix, 8);
+ end if;
+
+ end if;
+ end process fifo_mem;
+
+end fifo_ft_memory_arch;
+
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- VHDL model of A/D-converter Texas ADS1271
+-----------------------------------------------------------------------------
+
+-- NOTE! This is a model for simulation only. It is not
+-- coded to be synthezised.
+
+-- SPI interface format, 512 clock cycles/conversion
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity ads1271_model is
+ port (
+ analog_in : in signed(23 downto 0); -- Analog input signal
+ clk : in std_logic; -- Conversion clock
+ sclk : in std_logic; -- SPI clock
+ n_sync : in std_logic; -- Input sync signal, active low
+ din : in std_logic; -- Serial data in
+ dout : out std_logic; -- Serial data out
+ n_drdy : out std_logic := '1'); -- Data ready, active low
+end ads1271_model;
+
+
+
+architecture ads1271_model_arch of ads1271_model is
+
+ signal analog_data : signed(23 downto 0) := to_signed(0, 24);
+ shared variable conv_timer : integer := 2; -- Data conversion rate
+ shared variable sdata_counter : integer := -1; -- Controls dout bits
+ signal din_mem : std_logic := '0'; -- 'din' memory
+ signal drdy_ff : std_logic;
+ signal clk_del : std_logic := '0'; -- Delayed clk signal
+ signal sclk_del : std_logic := '0'; -- Delayed sclk signal
+ signal ct_is_one : std_logic; -- Locally generated sync
+ signal ct_is_zero : std_logic; -- Locally generated sync
+
+
+begin -- ads1271_model_arch
+
+ n_drdy <= drdy_ff or ct_is_one after 8 ns;
+ sclk_del <= sclk after 2 ns;
+ clk_del <= clk after 1 ns;
+
+
+ -- purpose: Data conversion circuitry
+ -- type : sequential
+ -- inputs : clk_del
+ -- outputs: dout, ct_is_one
+ convert : process (clk_del)
+ begin -- process convert
+ if falling_edge(clk_del) then -- falling clock edge
+ ct_is_one <= '0';
+ ct_is_zero <= '0';
+ if n_sync = '0' then
+ conv_timer := (128*512); -- Reloading the FIR takes a while
+ ct_is_one <= '1';
+ else
+ conv_timer := conv_timer - 1;
+ if conv_timer <= 0 then -- Conversion rate number
+ conv_timer := 512;
+ sdata_counter := 23; -- MSBit comes first
+ ct_is_zero <= '1';
+ end if; -- conv_timer <= 0
+ if conv_timer = 1 then
+ ct_is_one <= '1';
+ end if; -- conv_timer = 1
+ if conv_timer = 512 then
+ analog_data <= analog_in; -- Data sampling, data av. after 512 clock's
+ end if; -- conv_timer = 512
+ end if; -- n_sync = '0'
+ end if; -- falling_edge(clk_del)
+
+ end process convert;
+
+
+
+ -- purpose: Serial data interface control
+ -- type : sequential
+ -- inputs : sclk_del
+ -- outputs: dout
+ dataout : process (sclk_del)
+
+ begin -- process dataout
+ if sclk_del'event then
+ if sclk_del = '0' then -- falling clock edge
+ if sdata_counter >= 0 then
+ dout <= 'X' after 5 ns;
+ dout <= analog_data(sdata_counter) after 12 ns;
+ sdata_counter := sdata_counter - 1;
+ else
+ dout <= 'X' after 5 ns;
+ dout <= din_mem after 12 ns;
+ end if;
+ else
+ -- rising clock edge samples din
+ din_mem <= din;
+ end if;
+ end if;
+ end process dataout;
+
+
+
+ -- purpose: Controls the drdy_ff signal
+ -- type : sequential
+ -- inputs : sclk_del, ct_is_zero
+ -- outputs: drdy_ff
+ readyctl : process (sclk_del, ct_is_zero)
+ begin -- process readyctl
+ if ct_is_zero = '1' then -- asynchronous reset (active high)
+ drdy_ff <= '0';
+ elsif falling_edge(sclk_del) then -- falling clock edge
+ drdy_ff <= '1';
+ end if;
+ end process readyctl;
+
+end ads1271_model_arch;
+
+
+
+
+
+-----------------------------------------------------------------------------
+-- SPI slave with secondary spi master port
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.polyamplib.all;
+
+
+entity spi_slave is
+
+ port (
+ -- Main controls
+ fastclk : in std_logic;
+ spi_tx : in std_logic_vector(31 downto 0); -- Data to be sent
+ spi_rx : out std_logic_vector(31 downto 0); -- Data to be received
+ spi_op : out std_logic; -- Read/Write status/data/command
+
+ -- Slave port, connected to CPU
+ mosi : in std_logic;
+ miso : out std_logic;
+ sck : in std_logic; -- SPI clock
+ en_adc : in std_logic; -- Active low, enable ADC
+ en_incl : in std_logic; -- Active low, enable inclinometer
+
+ -- Master port, connected to inclinometer
+ incl_miso : in std_logic;
+ incl_mosi : out std_logic;
+ incl_sck : out std_logic;
+ incl_ena : out std_logic); -- Active low, enable inclinometer
+end spi_slave;
+
+
+
+architecture spi_slave_arch of spi_slave is
+
+ type state_type is (idle, load, shift, relax);
+ signal state : state_type := idle; -- Controlling state machine
+
+ signal enable_inclinometer : std_logic := '0';
+ signal enable_adc : std_logic := '0';
+ signal adc_miso : std_logic;
+ signal adc_load : std_logic := '0';
+-- signal g_miso : std_logic register := '0'; -- guarded miso signal
+ signal adc_sck : std_logic;
+ signal tx_sck : std_logic;
+ signal delayed_adc_sck : std_logic; -- Delayed, for edge detection
+
+
+begin -- spi_slave_arch
+
+ -- Transmit shift register
+ tx_sr : sr_piso_s generic map (
+ LENGTH => 32,
+ DIR => 1) -- Shift left => MSB first
+ port map (
+ fastclk => fastclk,
+ clk_en => tx_sck,
+ load_en => adc_load,
+ par_in => spi_tx,
+ ser_in => '0',
+ ser_out => adc_miso);
+
+ -- Receive shift register
+ rx_sr : sr_sipo generic map (
+ LENGTH => 32,
+ EDGE => 1, -- Positive edge
+ DIR => 1) -- Shift left => MSB first
+ port map (
+ clk => adc_sck,
+ ser_in => mosi,
+ par_out => spi_rx);
+
+
+ -- Passthru signals
+ incl_sck <= sck after 1 ns;
+ incl_mosi <= mosi after 1 ns;
+ incl_ena <= not enable_inclinometer after 1 ns; -- Active low output
+
+ -- Enable and clock
+ enable_inclinometer <= not en_incl and en_adc after 1 ns;
+ enable_adc <= not en_adc after 1 ns;
+ adc_sck <= sck or en_adc after 1 ns; -- Clock is driven high at inactive state
+ tx_sck <= (not adc_sck) and delayed_adc_sck after 1 ns; -- sck negative edge trigger
+
+ -- Output data
+-- miso <= g_miso;
+
+
+ -- purpose: ADC controls miso
+-- talkto_adc : block (enable_adc = '1')
+-- begin -- block talkto_adc
+-- g_miso <= guarded adc_miso;
+-- end block talkto_adc;
+
+
+ -- purpose: Inclinometer controls miso
+-- talkto_incl : block (enable_inclinometer = '1')
+-- begin -- block talkto_incl
+-- g_miso <= guarded incl_miso;
+-- end block talkto_incl;
+
+
+ -- Instead of the guarded assignments above
+ miso <= adc_miso when enable_inclinometer = '0' else incl_miso;
+
+
+ -- purpose: SPI slave controller state machine
+ -- type : sequential
+ -- inputs : fastclk, enable_adc
+ -- outputs: adc_load
+ input_active : process (fastclk)
+
+ begin -- process input_active
+ if rising_edge(fastclk) then -- rising clock edge
+ delayed_adc_sck <= adc_sck;
+ adc_load <= '1' after 1 ns;
+ spi_op <= '0' after 1 ns;
+ case state is
+ when idle => if enable_adc = '1' then
+ state <= load;
+ end if;
+
+ when load => state <= shift;
+
+ when shift => adc_load <= '0' after 1 ns;
+ if enable_adc = '0' then
+ state <= relax;
+ spi_op <= '1' after 1 ns;
+ end if;
+
+ when relax => state <= idle;
+
+ when others => state <= idle;
+ end case;
+ end if;
+ end process input_active;
+
+end spi_slave_arch;
+
+
+
+
+-----------------------------------------------------------------------------
+-- SPI slave with burst capabilities and with secondary spi master port
+-- NOTE! Spi mode 2
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.polyamplib.all;
+
+
+entity spi_slave_burst is
+
+ port (
+ -- Main controls
+ fastclk : in std_logic;
+ spi_tx : in std_logic_vector(31 downto 0); -- Data to be sent
+ spi_rx : out std_logic_vector(31 downto 0); -- Data to be received
+ exec_cmd : out std_logic; -- Write command/data
+ fifo_read : out std_logic; -- Read status/data
+
+ -- Slave port, connected to CPU
+ mosi : in std_logic;
+ miso : out std_logic;
+ sck : in std_logic; -- SPI clock
+ en_adc : in std_logic; -- Active low, enable ADC
+ en_incl : in std_logic; -- Active low, enable inclinometer
+
+ -- Master port, connected to inclinometer
+ incl_miso : in std_logic;
+ incl_mosi : out std_logic;
+ incl_sck : out std_logic;
+ incl_ena : out std_logic); -- Active low, enable inclinometer
+end spi_slave_burst;
+
+
+
+architecture spi_slave_burst_arch of spi_slave_burst is
+
+-- type state_type is (idle, load, shift, relax);
+-- signal state : state_type := idle; -- Controlling state machine
+
+ signal bitcounter : unsigned(4 downto 0) := to_unsigned(0, 5); -- Range 0..31
+ signal enable_inclinometer : std_logic := '0';
+ signal enable_adc : std_logic := '0';
+ signal adc_miso : std_logic;
+ signal clk_tx_sr : std_logic := '0';
+ signal load_tx_sr : std_logic := '0';
+
+ signal sck_r1 : std_logic; -- Delayed, for edge detection
+ signal sck_r2 : std_logic; -- Delayed, for edge detection
+ signal sck_negedge : std_logic; -- Negative edge
+ signal sck_posedge : std_logic; -- Positive edge
+ signal enable_adc_r1 : std_logic; -- Delayed, for edge detection
+ signal enable_adc_r2 : std_logic; -- Delayed, for edge detection
+ signal enable_adc_negedge : std_logic; -- Negative edge
+
+ signal bitcounter_zero : std_logic;
+ signal bitcounter_one : std_logic;
+ signal exec_ff : std_logic := '0'; -- Enable the execute signal
+ signal load_ff : std_logic := '0'; -- Enable the load signal
+
+
+begin -- spi_slave_burst_arch
+
+ -- Transmit shift register
+ tx_sr : sr_piso_s generic map (
+ LENGTH => 32,
+ DIR => 1) -- Shift left => MSB first
+ port map (
+ fastclk => fastclk,
+ clk_en => clk_tx_sr,
+ load_en => load_tx_sr,
+ par_in => spi_tx,
+ ser_in => '0',
+ ser_out => adc_miso);
+
+ -- Receive shift register
+ rx_sr : sr_sipo generic map (
+ LENGTH => 32,
+ EDGE => 1, -- Positive edge
+ DIR => 1) -- Shift left => MSB first
+ port map (
+ clk => sck_negedge,
+ ser_in => mosi,
+ par_out => spi_rx);
+
+
+ -- Passthru signals
+ incl_sck <= sck after 1 ns;
+ incl_mosi <= mosi after 1 ns;
+ incl_ena <= not enable_inclinometer after 1 ns; -- Active low output
+
+ -- Enable and clock
+ enable_inclinometer <= not en_incl and en_adc after 1 ns;
+ enable_adc <= not en_adc after 1 ns;
+
+ sck_posedge <= sck_r1 and (not sck_r2) after 1 ns; -- sck Positive edge
+ sck_negedge <= sck_r2 and (not sck_r1) after 1 ns; -- sck Negative edge
+
+ enable_adc_negedge <= enable_adc_r1 and (not enable_adc_r2) after 1 ns;
+ fifo_read <= sck_posedge and bitcounter_one after 1 ns;
+ load_tx_sr <= enable_adc_negedge or
+ (sck_negedge and bitcounter_zero and (not load_ff)) after 1 ns;
+ exec_cmd <= bitcounter_zero and exec_ff and sck_posedge after 1 ns;
+ clk_tx_sr <= sck_posedge or enable_adc_negedge after 1 ns;
+
+ -- Instead of the guarded assignments above
+ miso <= adc_miso when enable_inclinometer = '0' else incl_miso after 1 ns;
+
+
+ -- purpose: SPI slave controller state machine
+ -- type : sequential
+ -- inputs : fastclk, sck, enable_adc, bitcounter, load_tx_sr
+ -- outputs: sck_r1, sck_r2, enable_adc_r1, enable_adc_r2, bitcounter
+ input_active : process (fastclk)
+
+ begin -- process input_active
+ if rising_edge(fastclk) then -- rising clock edge
+ sck_r2 <= sck_r1 after 1 ns;
+ sck_r1 <= sck after 1 ns;
+
+ enable_adc_r2 <= enable_adc_r1 after 1 ns;
+ enable_adc_r1 <= enable_adc after 1 ns;
+
+ if enable_adc_negedge = '1' then
+ bitcounter <= to_unsigned(0, 5) after 1 ns;
+ else if sck_negedge = '1' then
+ bitcounter <= bitcounter + 1 after 1 ns;
+ end if;
+ end if;
+
+ if bitcounter = 0 then
+ bitcounter_zero <= '1' after 1 ns;
+ else
+ bitcounter_zero <= '0' after 1 ns;
+ end if;
+
+ if bitcounter = 1 then
+ bitcounter_one <= '1' after 1 ns;
+ else
+ bitcounter_one <= '0' after 1 ns;
+ end if;
+
+ if enable_adc = '0' then
+ exec_ff <= '0' after 1 ns;
+ elsif bitcounter = 2 then
+ exec_ff <= '1' after 1 ns;
+ end if;
+
+ if load_tx_sr = '1' then
+ load_ff <= '1' after 1 ns;
+ elsif bitcounter = 2 then
+ load_ff <= '0' after 1 ns;
+ end if;
+
+ end if;
+ end process input_active;
+
+end spi_slave_burst_arch;
+
+
+
+
+
+----------------------------------------------------------------------
+-- Command decoder function
+----------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity command_decoder is
+ port (
+ addr_data : in std_logic_vector(31 downto 0); -- Input address/data
+ decode : in std_logic; -- Single cycle decode pulse
+ fastclk : in std_logic; -- Master clock (not used for now)
+ sel_nulcmd : out std_logic; -- NULL command (no operation)
+ sel_adclk0 : out std_logic; -- Select sampling clock, ad0.
+ sel_adclk1 : out std_logic; -- Select sampling clock, ad1.
+ sel_adclk2 : out std_logic; -- Select sampling clock, ad2.
+ sel_adclk3 : out std_logic; -- Select sampling clock, ad3.
+ sel_adclk4 : out std_logic; -- Select sampling clock, ad4.
+ sel_adclk5 : out std_logic; -- Select sampling clock, ad5.
+ sel_adclk6 : out std_logic; -- Select sampling clock, ad6.
+ sel_adclk7 : out std_logic; -- Select sampling clock, ad7.
+ resync_adc : out std_logic; -- Resynchronize all ADC's
+ write_ctrl : out std_logic; -- Write to control-signal register
+ start_adcs : out std_logic; -- Start AD-conversion
+ stop_adcs : out std_logic); -- Stop AD-conversion
+end command_decoder;
+
+
+architecture command_decoder_arch of command_decoder is
+
+begin -- command_decoder_arch
+
+ sel_nulcmd <= '1' when (addr_data(27 downto 24) = "0000") and decode = '1' else '0';
+ sel_adclk0 <= '1' when (addr_data(27 downto 24) = "0001") and decode = '1' else '0';
+ sel_adclk1 <= '1' when (addr_data(27 downto 24) = "0010") and decode = '1' else '0';
+ sel_adclk2 <= '1' when (addr_data(27 downto 24) = "0011") and decode = '1' else '0';
+ sel_adclk3 <= '1' when (addr_data(27 downto 24) = "0100") and decode = '1' else '0';
+ sel_adclk4 <= '1' when (addr_data(27 downto 24) = "0101") and decode = '1' else '0';
+ sel_adclk5 <= '1' when (addr_data(27 downto 24) = "0110") and decode = '1' else '0';
+ sel_adclk6 <= '1' when (addr_data(27 downto 24) = "0111") and decode = '1' else '0';
+ sel_adclk7 <= '1' when (addr_data(27 downto 24) = "1000") and decode = '1' else '0';
+ resync_adc <= '1' when (addr_data(27 downto 24) = "1001") and decode = '1' else '0';
+ write_ctrl <= '1' when (addr_data(27 downto 24) = "1010") and decode = '1' else '0';
+ start_adcs <= '1' when (addr_data(27 downto 24) = "1011") and decode = '1' else '0';
+ stop_adcs <= '1' when (addr_data(27 downto 24) = "1100") and decode = '1' else '0';
+
+end command_decoder_arch;
+
+
+
+
+----------------------------------------------------------------------
+-- ADC clock multiplexer function
+----------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity clockmux is
+ port (
+ clk24M : in std_logic; -- Input clocks, 24 576 000
+ clk4M : in std_logic; -- 4 096 000
+ clk2M : in std_logic; -- 2 048 000
+ clk1M : in std_logic; -- 1 024 000
+ clk512k : in std_logic; -- 512 000
+ clk256k : in std_logic; -- 256 000
+ clk128k : in std_logic; -- 128 000
+ sel : in unsigned(2 downto 0); -- Mux select input
+ clkout : out std_logic); -- Output clock
+end clockmux;
+
+
+architecture clockmux_arch of clockmux is
+
+begin -- clockmux_arch
+
+ with sel select
+ clkout <=
+ clk128k when "000",
+ clk256k when "001",
+ clk512k when "010",
+ clk1M when "011",
+ clk2M when "100",
+ clk4M when "101",
+ clk24M when "110",
+ clk24M when others;
+
+end clockmux_arch;
+
+
+
+
+-------------------------------------------------------------------------------
+-- SPI master for simulation and test (no synth.)
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity spi_master is
+ port (
+ -- Hardware ports
+ miso : in std_logic;
+ mosi : out std_logic;
+ sck : inout std_logic := '0';
+ en_adval : out std_logic := '1';
+ en_incl : out std_logic := '1';
+
+ -- Simulation ports
+ data_to_spi : in std_logic_vector(31 downto 0);
+ data_from_spi : out std_logic_vector(31 downto 0);
+ start : in std_logic;
+ busy : out std_logic := '0';
+ running : in std_logic);
+end spi_master;
+
+
+architecture spi_master_arch of spi_master is
+
+ type state_type is (idle, load, shift);
+ signal state : state_type := idle;
+ signal start_mem : std_logic := '0';
+
+
+begin -- spi_master_arch
+
+
+ -----------------------------------------------------------------------------
+
+ -- Assume that data_to_spi is defined before this process is triggered
+ spi_rxtx : process (sck)
+
+ variable bit_index : integer := 0;
+
+ begin -- process spi_rxtx
+ if sck'event then
+ if sck = '1' then -- rising clock edge
+ start_mem <= start;
+ case state is
+ when idle => if start = '1' and start_mem = '0' then -- Start rising
+ -- edge
+ en_adval <= '0' after 15 ns;
+ busy <= '1' after 2 ns;
+ state <= load;
+ bit_index := 31;
+ end if;
+
+ when load => data_from_spi(bit_index) <= miso;
+ state <= shift;
+
+ when shift => bit_index := bit_index - 1;
+ if bit_index < 0 then
+ state <= idle;
+ en_adval <= '1' after 15 ns;
+ busy <= '0' after 2 ns;
+ else
+ data_from_spi(bit_index) <= miso;
+ end if;
+ when others => state <= idle;
+ end case;
+ end if; -- sck = '1' else ...
+
+ if sck = '0' and (state = load or state = shift) then
+ mosi <= data_to_spi(bit_index) after 1 ns;
+ end if;
+
+ end if; -- sck'event
+ end process spi_rxtx;
+
+ -----------------------------------------------------------------------------
+
+ spi_clk : process
+ begin -- process spi_clk
+ while running = '1' loop
+ sck <= not sck;
+ wait for 50 ns;
+ end loop;
+ sck <= not sck;
+ wait for 50 ns;
+ sck <= not sck;
+ wait for 50 ns;
+ sck <= not sck;
+ wait for 50 ns;
+ sck <= not sck;
+ wait for 50 ns;
+ wait;
+ end process spi_clk;
+
+end spi_master_arch;
+
+
+
+----------------------------------------------------------------------
+-- Synchronization logic
+----------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity sync_logic_2 is
+
+ port (
+ start_adcs : in std_logic; -- Start command
+ stop_adcs : in std_logic; -- Stop command
+ reset : in std_logic; -- Active high
+ hwsync : in std_logic; -- Hardware sync
+ fastclk : in std_logic; -- Master clock
+ enable_adcvalues : out std_logic); -- Enable reception of values
+
+end sync_logic_2;
+
+
+
+architecture sync_logic_2_arch of sync_logic_2 is
+
+ signal del_sync_1 : std_logic; -- 1'st delay
+ signal del_sync_2 : std_logic; -- 2'nd delay
+ signal sr_set : std_logic; -- Set input to SR-latch
+ signal sr : std_logic := '0'; -- sr Q output, entity output
+
+
+begin -- sync_logic_2_arch
+
+ enable_adcvalues <= sr;
+ sr_set <= (del_sync_1 and (not del_sync_2)) xor start_adcs;
+
+
+ -- purpose: Two D-latches and one SR-latch is controlled
+ -- type : sequential
+ -- inputs : fastclk, reset, start_adcs, stop_adcs, hwsync
+ -- outputs: sr
+ registered_logic : process (fastclk, reset)
+ begin -- process registered_logic
+ if reset = '1' then -- asynchronous reset
+ del_sync_1 <= '0' after 2 ns;
+ del_sync_2 <= '0' after 2 ns;
+ sr <= '0' after 2 ns;
+ elsif rising_edge(fastclk) then -- rising clock edge
+ del_sync_1 <= hwsync after 2 ns;
+ del_sync_2 <= del_sync_1 after 2 ns;
+ if stop_adcs = '1' then
+ sr <= '0' after 2 ns;
+ elsif sr_set = '1' then
+ sr <= '1' after 2 ns;
+ end if;
+
+ end if;
+ end process registered_logic;
+
+end sync_logic_2_arch;