From ad89405df706646fb2e06f70203f0798610085a8 Mon Sep 17 00:00:00 2001 From: Greek Date: Mon, 22 Mar 2021 00:21:32 +0100 Subject: [PATCH] Update README --- Readme.md | 14 +-- src/PMOD_AD1.vhd | 269 ----------------------------------------------- 2 files changed, 7 insertions(+), 276 deletions(-) delete mode 100644 src/PMOD_AD1.vhd diff --git a/Readme.md b/Readme.md index 00a5d80..de22f35 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # Project Structure -* **doc** Contains all releavnt documentation need for this project +* **doc** Contains all relevant documentation needed for this project * **download** Contains various files downloaded for this project * **corebundle-mst_lab.zip** First version of Custom Xillybus IP Core implementation generated by "IP Core Factory" * `xillybus_debug`: Upstream, 32-bits, 256 B/s, General Purpose @@ -33,7 +33,7 @@ Zedboard Pin | Description --------------------------------|--------------- JC1 PMOD Connector (Upper Row) | PMOD-AD1 Board JD1 PMOD Connector (Upper Row) | PMOD-DA3 Board -JA1 PMOD JA1 Pin | Optional External Clock [NOTE: Clk has to be connected in VHDl and PLL has to be reconfigured accordingly] +JA1 PMOD JA1 Pin | Optional External Clock [NOTE: Clk has to be connected in VHDL and PLL has to be reconfigured accordingly] JA1 PMOD JA4 Pin | External SYNC Pulse [NOTE: if pin is left unconnected (floating), it will register as a pulse] SW7 | Standby / Write Mode (Allows xillinux to write configuration) LED7 | Standby Status @@ -47,9 +47,9 @@ BTNU | Debug value reset This project implements the above feedback loop in FPGA logic. The components of the feedback loop are analysed below: * **ADC** The ADC (PMOD-AD1) is capable of operating at a maximum frequency of 20 MHz, and converting an analog signal every 18 clock cycles (ca 1.1 MHz Sampling Frequency). All PMOD Connectors on the Zedboard are fixed to 3.3V, hence the ADC can convert analog signals in the range 0V-3.3V to 12-bits. -* **ADC** The DAC (PMOD-DA3) is capable of operating at a maximum frequency of 50 MHz, and converting a digital signal every 16 clock cycles (ca 1.25 MHz). The DAC uses an internal 2.5 V Voltage reference (uncorrelated to the used VCC Voltage), and can thus convert 16-bits to 0V-2.5V. +* **DAC** The DAC (PMOD-DA3) is capable of operating at a maximum frequency of 50 MHz, and converting a digital signal every 16 clock cycles (ca 1.25 MHz). The DAC uses an internal 2.5 V Voltage reference (uncorrelated to the used VCC Voltage), and can thus convert 16-bits to 0V-2.5V. * **DELAY LINE** The delay line allows to delay the converted ADC values by a pre-specified amount of clock cycles. -* **SCALER** The scaler allows the converted ADc values to be downscaled. It uses a 5-bit multiplication factor that is intepreted as a 1Q4 (1-Bit Integer, 4-Bit Fractional) fixed point number. Note that the factor should only take values between 0 and 16 (decimal), as due to the internal connection (truncat highest bit) using higher numbers can (and will) result to overflow conditions. +* **SCALER** The scaler allows the converted ADC values to be downscaled. It uses a 5-bit multiplication factor that is intepreted as a 1Q4 (1-Bit Integer, 4-Bit Fractional) fixed point number. Note that the factor should only take values between 0 and 16 (decimal), as due to the internal connection (truncat highest bit) using higher numbers can (and will) result to overflow conditions. e.g. A value of 16(decimal) is intepreted as scaling by 1, a value of 15 (decimal) is intepreted as scaling by 0.9375, and a value of 8 is is intepreted as scaling by 0.5. * **ADD/SUB** The ADD/SUB allows to either add or subtract the scaler output from the MUX output. (Allowing to either implement a positive, or negative feedback loop). * **MUX** The MUX selects between the second ADC channel or zero (GND), allowing a "neutral" feedback. @@ -58,7 +58,7 @@ e.g. A value of 16(decimal) is intepreted as scaling by 1, a value of 15 (decima The whole system is clocked at 20 MHz (highest supported frequency of ADC). The *ADD/SUB* and *Scaler* have a 1-stage pipeline, meaning that if the *Delay Line* is configured with 0 delay, the feedback loop follows the 18 clock cycle cadence of the ADC without additional delay. -In order to re-align the inputs of the *ADD/SUB*, the second channel of the ADC is latched (delayed) for one clock cycle (not shown in diagram). +In order to re-align the inputs of the *ADD/SUB*, the second channel of the ADC is latched (delayed) for one clock cycle (not shown in diagram) to compensate for the Scaler pipeline. # USAGE @@ -91,7 +91,7 @@ ADDSUB_MODE ADD_INPUT_MUX DELAY FACTOR TIMESTAMP * ADDSUB_MODE: Select feedback mode (0=negative, 1=positive) * ADD_INPUT_MUX: Select feedback input (0=GND[only ADC Input 1], 1=ADC Input 2[Both ADC inputs are used]) -* DELAY: Clock cycles counts (50 ns period) to delay the feedback signal [0-255] +* DELAY: Clock cycle counts (50 ns period) to delay the feedback signal [0-255] * FACTOR: Multiplication factor to apply to the feedback signal [0-16] (NOTE: Integer is intepreted as a 1Q4 Fixed Point Number!) * TIMESTAMP: Defines the clock count number from the sync pulse from which on the configurations settings will be applied. [32-bit unsigned integer] @@ -100,5 +100,5 @@ The FPGA logic allows debug values to be sent to the Linux via the `xillybus_deb Currently the FPGA logic sends every second the max values of the both ADC channels, Scaler output, and DAC. The max values can be externally reset (see Mapping). -The `read_debug.c` C program can be used to read the debug values. Since the program enters an endless loop, a signal handler has beeen implemented and the program can be safely terminated with `CTRL-C` and co. +The `read_debug.c` C program can be used to read the debug values. Since the program enters an endless loop, a signal handler has beeen implemented and the program can be safely terminated with `CTRL-C` & CO. e.g. `./read_debug /dev/xillybus_debug` diff --git a/src/PMOD_AD1.vhd b/src/PMOD_AD1.vhd deleted file mode 100644 index 5520b38..0000000 --- a/src/PMOD_AD1.vhd +++ /dev/null @@ -1,269 +0,0 @@ -------------------------------------------------------------------------- --- AD1_controller.VHD -------------------------------------------------------------------------- --- Author : Todd Harless --- CopyRight 2005 Digilent, Inc. -------------------------------------------------------------------------- --- Description : This file is the VHDL code for a PMOD-AD1 controller. --- -------------------------------------------------------------------------- --- Revision History: --- 07/11/2005 Created (Todd Harless) --- 08/09/2005 revision 0.1 (Todd Harless) -------------------------------------------------------------------------- - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_ARITH.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - - - -------------------------------------------------------------------------- ---Title : AD1 controller entity --- --- Inputs : 3 --- Outputs : 3 --- --- Description : This is the AD1 controller entity. The input ports are --- a 50 MHz clock and an asynchronous --- reset button along with the data from the ADC7476 that --- is serially shifted in on each clock cycle. The outputs --- are the SCLK signal which clocks the PMOD-AD1 board at --- 12.5 MHz and a chip select signal (CS) that latches the --- data into the PMOD-AD1 board as well as an 12-bit output --- vector labeled DATA_OUT which can be used by any --- external components. --- --------------------------------------------------------------------------- - - -entity AD1_controller is - Port ( - --General usage - CLK : in std_logic; -- System Clock (50MHz) - RST : in std_logic; - - --Pmod interface signals - SDATA1 : in std_logic; - SDATA2 : in std_logic; - SCLK : out std_logic; - CS : out std_logic; - - --User interface signals - DATA1 : out std_logic_vector(11 downto 0); - DATA2 : out std_logic_vector(11 downto 0); - START : in std_logic; - DONE : out std_logic - - - ); -end AD1_controller; - -architecture AD1 of AD1_controller is - --------------------------------------------------------------------------------- ---Title : Local signal assignments --- --- Description : The following signals will be used to drive the processes of --- this VHDL file. --- --- current_state: This signal will be the pointer that will point at the --- current state of the Finite State Machine of the --- controller. --- next_state : This signal will be the pointer that will point at the --- current state of the Finite State Machine of the --- controller. --- temp1 : This is a 16-bit vector that will store the 16-bits of data --- that are serially shifted-in form the first ADC7476 chip inside the --- PMOD-AD1 board. --- temp2 : This is a 16-bit vector that will store the 16-bits of data --- that are serially shifted-in form the second ADC7476 chip inside the --- PMOD-AD1 board. --- dat1 : This is a 12-bit vector that will store the 12-bits of actual data --- that are serially shifted-in form the first ADC7476 chip inside the --- PMOD-AD1 board. --- dat2 : This is a 12-bit vector that will store the 12-bits of actual data --- that are serially shifted-in form the second ADC7476 chip inside the --- PMOD-AD1 board. --- clk_div : This will be the divided 12.5 MHz clock signal that will --- clock the PMOD-AD1 board --- clk_counter : This counter will be used to create a divided clock signal. --- --- shiftCounter : This counter will be used to count the shifted data from the --- ADC7476 chip inside the PMOD-AD1 board. --- enShiftCounter : This signal will be used to enable the counter for the shifted --- data from the ADC7476 chip inside the PMOD-AD1 board. --- enParalelLoad : This signal will be used to enable the load in a register the shifted --- data. --------------------------------------------------------------------------------- - -type states is (Idle, - ShiftIn, - SyncData); - signal current_state : states; - signal next_state : states; - - signal temp1 : std_logic_vector(15 downto 0) := (others => '0'); - signal temp2 : std_logic_vector(15 downto 0) := (others => '0'); - signal dat1 : std_logic_vector(11 downto 0):= x"000"; - signal dat2 : std_logic_vector(11 downto 0):= x"000"; - signal clk_div : std_logic; - signal clk_counter : std_logic_vector(27 downto 0); - signal shiftCounter : std_logic_vector(3 downto 0) := x"0"; - signal enShiftCounter: std_logic; - signal enParalelLoad : std_logic; - - - -begin - - - --------------------------------------------------------------------------------- ---Title : clock divider process --- --- Description : This is the process that will divide the 50 MHz clock --- down to a clock speed of 12.5 MHz to drive the ADC7476 chip. --------------------------------------------------------------------------------- - clock_divide : process(rst,clk) - begin - if rst = '1' then - clk_counter <= "0000000000000000000000000000"; - elsif (clk = '1' and clk'event) then - clk_counter <= clk_counter + '1'; - end if; - end process; - - clk_div <= clk_counter(1); - SCLK <= not clk_counter(1); - ------------------------------------------------------------------------------------ --- --- Title : counter --- --- Description: This is the process were the teporary registers will be loaded and --- shifted.When the enParalelLoad signal is generated inside the state --- the temp1 and temp2 registers will be loaded with the 8 bits of control --- concatenated with the 8 bits of data. When the enShiftCounter is --- activated, the 16-bits of data inside the temporary registers will be --- shifted. A 4-bit counter is used to keep shifting the data --- inside temp1 and temp2 for 16 clock cycles. --- ------------------------------------------------------------------------------------ - -counter : process(clk_div, enParalelLoad, enShiftCounter) - begin - if (clk_div = '1' and clk_div'event) then - - if (enShiftCounter = '1') then - temp1 <= temp1(14 downto 0) & SDATA1; - temp2 <= temp2(14 downto 0) & SDATA2; - shiftCounter <= shiftCounter + '1'; - elsif (enParalelLoad = '1') then - shiftCounter <= "0000"; - dat1 <= temp1(11 downto 0); - dat2 <= temp2(11 downto 0); - end if; - end if; - end process; - DATA1 <= dat1 ; - DATA2 <= dat2 ; ---------------------------------------------------------------------------------- --- --- Title : Finite State Machine --- --- Description: This 3 processes represent the FSM that contains three states. The first --- state is the Idle state in which a temporary registers are --- assigned the updated value of the input "DATA1" and "DATA2". The next state --- is the ShiftIn state where the 16-bits of --- data from each of the ADCS7476 chips are left shifted in the temp1 and temp2 shift registers. --- The third --- state SyncData drives the output signal CS high for --- 1 clock period, and the second one in the Idle state telling the ADCS7476 to mark the end of the conversion. --- Notes: The data will change on the lower edge of the clock signal. Their --- is also an asynchronous reset that will reset all signals to their --- original state. --- ------------------------------------------------------------------------------------ - ------------------------------------------------------------------------------------ --- --- Title : SYNC_PROC --- --- Description: This is the process were the states are changed synchronously. At --- reset the current state becomes Idle state. --- ------------------------------------------------------------------------------------ -SYNC_PROC: process (clk_div, rst) - begin - if (clk_div'event and clk_div = '1') then - if (rst = '1') then - current_state <= Idle; - else - current_state <= next_state; - end if; - end if; - end process; - ------------------------------------------------------------------------------------ --- --- Title : OUTPUT_DECODE --- --- Description: This is the process were the output signals are generated --- unsynchronously based on the state only (Moore State Machine). --- ------------------------------------------------------------------------------------ -OUTPUT_DECODE: process (current_state) - begin - if current_state = Idle then - enShiftCounter <='0'; - DONE <='1'; - CS <='1'; - enParalelLoad <= '0'; - elsif current_state = ShiftIn then - enShiftCounter <='1'; - DONE <='0'; - CS <='0'; - enParalelLoad <= '0'; - else --if current_state = SyncData then - enShiftCounter <='0'; - DONE <='0'; - CS <='1'; - enParalelLoad <= '1'; - end if; - end process; - ----------------------------------------------------------------------------------- --- --- Title : NEXT_STATE_DECODE --- --- Description: This is the process were the next state logic is generated --- depending on the current state and the input signals. --- ------------------------------------------------------------------------------------ - NEXT_STATE_DECODE: process (current_state, START, shiftCounter) - begin - - next_state <= current_state; --default is to stay in current state - - case (current_state) is - when Idle => - if START = '1' then - next_state <= ShiftIn; - end if; - when ShiftIn => - if shiftCounter = x"F" then - next_state <= SyncData; - end if; - when SyncData => - if START = '0' then - next_state <= Idle; - end if; - when others => - next_state <= Idle; - end case; - end process; - - -end AD1;