Archana Narayanan

Members
  • Content Count

    5
  • Joined

  • Last visited

  1. Hi @D@n, My PC-FPGA link works fine since I had this tested by sending characters to FPGA and displaying them on the LED's. Then,I also made sure I tried a simple UART transmitter receiver code to send and read-back the same character .This ensured the PC-FPGA-PC link works fine as well. Hi @jpeyron, As suggested,since I wanted to control all the processes (ADC,CCD,FIFO,UART), I tested them one at a time. I replaced the switch control for CCD, then ADC and so on by a UART(PC->FPGA) receiver process. It seemed to work alright however I encountered a problem when I automated the reset switch. So, my UART receiver code here has a reset input. All the reset inputs in multiple parts of my code were controlled by one UART-RX process. I could start the processes with an ASCII input from hyperterminal and stop it. But when I reset it,with say 'r' from the hyperterminal, I wasn't able to resume . After stumbling on it for a while, I realised, this was since the UART_RX(PC->FPGA link) in itself was reset and there was no way I could resume processes using UART link. A rather silly miss of course. I removed the reset in PC-> FPGA UART link and the problem seems to be resolved. Thanks y'all for your inputs.
  2. Hello, I am trying to send a character to FPGA from PC hyper terminal , for eg : 's' to start other processes in FPGA like initiating generation of CCD signals and sampling ADC et al and a different ascii character to stop the processes. I am able to send a ASCII character from PC hyper terminal and receive binary value it on FPGA LED's however I'm unable to use this for control. Please find my top level code below. 'Start' signal is to be controlling the initiation of other processes. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; Library UNISIM; use UNISIM.vcomponents.all; Library UNIMACRO; use UNIMACRO.vcomponents.all; use IEEE.MATH_REAL.ALL; ----------------------------------------------------- entity top_module is port( --------------------UART_GUI------------------------------- RxD : IN STD_LOGIC; RxData : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); ---COMMON INPUTS--- clk, rst : in std_logic; --send_ccd : in std_logic;---------------CCD control SH,ICG,master_ccd_clock : out std_logic; ----FOR AD7980-------- --sample: in std_logic; -------------- to start sampling samp_ind: out std_logic;---------------indicates sampling in process adc_cnv : out std_logic;---------------cnv for AD7980 adc_clk : inout std_logic;--------------SPI clock adc_miso : in std_logic;------------------output from AD7980 -------FIFO SIGNALS-------- WriteEn , ReadEn : in std_logic; -------------fifo controls full, empty : out std_logic ------------------indicates fifo status ); end top_module; architecture structural of top_module is ----------------------------------------------------------------------------UART CONTROL GUI------------------------------------- component receiver IS PORT ( clk : IN STD_LOGIC; reset : IN STD_LOGIC; RxD : IN STD_LOGIC; RxData : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END component receiver; ----------------------------------------FIFO COMPONENT DECLARATION ----------------------------------------------------------------- component fifo is port ( reset_rtl_0 : in STD_LOGIC; clk_100MHz : in STD_LOGIC; full_0 : out STD_LOGIC; din_0 : in STD_LOGIC_VECTOR ( 15 downto 0 ); wr_en_0 : in STD_LOGIC; empty_0 : out STD_LOGIC; dout_0 : out STD_LOGIC_VECTOR ( 15 downto 0 ); rd_en_0 : in STD_LOGIC ); end component fifo; -------------------------------------------------------------------------------------------------------------------------- signal fifo_data_out : STD_LOGIC_VECTOR (15 downto 0); signal adc_out : std_logic_vector(15 downto 0); signal start :std_logic; -------------------------UART_RX_FOR CONTROL_ OF_PROCESSES--------------------------------------------------------------- process(Clk,RxData) begin if RxData = "01110011" then start <= '1' ; elsif RxData = "01110000" then start <= '0'; else start <= '0'; end if; end process; --------------------AD7980PORTMAP---------------------------------------------------------------------------------- AD7980 : entity work.AD7980 port map ( clock => clk, sample => start, -- data output Dout => adc_out(15 downto 0), samp_ind => samp_ind, -- ADC connection adc_miso => adc_miso, adc_cnv => adc_cnv, adc_clk =>adc_clk ); ---------------------------------------------FIFO PORTMAP---------------------------------------------------------------- fifo_i: component fifo port map ( clk_100MHz => clk, din_0(15 downto 0) => adc_out(15 downto 0), dout_0(15 downto 0) => fifo_data_out(15 downto 0), empty_0 => empty, full_0 => full, rd_en_0 => ReadEn, reset_rtl_0 => rst, wr_en_0 => WriteEn ); ccd_control : entity work.TCD1103GFG port map ( clock => clk, send => start, SH => SH, ICG => ICG, master_ccd_clock => master_ccd_clock); ---------------------------------------------------------------UART GUI CONTROL--------------------------------------- uart_gui : entity work.receiver port map ( clk => clk, reset => rst, RxD => RxD, RxData => RxData ); end structural; Here is the UART receiver open source code I'm using that works LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; ENTITY receiver IS PORT ( clk : IN STD_LOGIC; reset : IN STD_LOGIC; RxD : IN STD_LOGIC; RxData : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END receiver; ARCHITECTURE behavioural OF receiver IS SIGNAL shift : STD_LOGIC; SIGNAL state : STD_LOGIC; SIGNAL nextstate : STD_LOGIC; SIGNAL bitcounter : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL samplecounter : STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL counter : STD_LOGIC_VECTOR(13 DOWNTO 0); SIGNAL rxshiftreg : STD_LOGIC_VECTOR(9 DOWNTO 0); SIGNAL clear_bitcounter : STD_LOGIC; SIGNAL inc_bitcounter : STD_LOGIC; SIGNAL inc_samplecounter : STD_LOGIC; SIGNAL clear_samplecounter : STD_LOGIC; constant clk_freq: integer := 100000000; constant baud_rate :integer := 9600; constant div_sample :integer := 4; constant div_counter :integer := (clk_freq/(baud_rate*div_sample)); constant mid_sample : integer := (div_sample/2); constant div_bit : integer := 10; BEGIN RxData <= rxshiftreg(8 DOWNTO 1); PROCESS (clk) BEGIN IF (clk'EVENT AND clk = '1') THEN IF (reset = '1') THEN state <= '0'; bitcounter <= "0000"; counter <= "00000000000000"; samplecounter <= "00"; ELSE counter <= counter + "00000000000001"; if (counter>= div_counter - 1) then counter <= "00000000000000"; state <= nextstate; IF (shift = '1') THEN rxshiftreg <= (RxD & rxshiftreg(9 DOWNTO 1)); END IF; IF (clear_samplecounter = '1') THEN samplecounter <= "00"; END IF; IF (inc_samplecounter = '1') THEN samplecounter <= samplecounter + "01"; END IF; IF (clear_bitcounter = '1') THEN bitcounter <= "0000"; END IF; IF (inc_bitcounter = '1') THEN bitcounter <= bitcounter + "0001"; END IF; END IF; END IF; END IF; END PROCESS; PROCESS (clk) BEGIN IF (clk'EVENT AND clk = '1') THEN shift <= '0'; clear_samplecounter <= '0'; inc_samplecounter <= '0'; clear_bitcounter <= '0'; inc_bitcounter <= '0'; nextstate <= '0'; CASE state IS WHEN '0' => IF (RxD = '1') THEN nextstate <= '0'; ELSE nextstate <= '1'; clear_bitcounter <= '1'; clear_samplecounter <= '1'; END IF; WHEN '1' => nextstate <= '1'; IF (samplecounter = (mid_sample - 1)) THEN shift <= '1'; END IF; IF (samplecounter = (div_sample - 1)) THEN IF (bitcounter = (div_bit - 1)) THEN nextstate <= '0'; END IF; inc_bitcounter <= '1'; clear_samplecounter <= '1'; ELSE inc_samplecounter <= '1'; END IF; WHEN OTHERS => nextstate <= '0'; END CASE; END IF; END PROCESS; end behavioural; I'm unsure if the issue is because of the number of clock cycles for which the character 's' exists. Please help me understand the miss here.
  3. Hey @jpeyron Yes, looks like that would be the right path to isolate the cause. Thanks, will try that. -Archana
  4. Hi @jpeyron, I tried using a FIFO with width=10 and depth 131087. I get the same result. PFA the summary of FIFO IP that I used. The sampling frequency of ADC is 75ksps at 2.7V My input is 650 hz and Vpp= 1.5V; continuous sine wave. I'm using the Pmod VDD at 3.3V to power the ADC. The baud rate is set to 9600 for UART. Thanks, Archana
  5. Hello, I am trying to interface MCP3008 with basys 3 using SPI and store the values in a FIFO and transmit the values to PC using UART. Initially, I designed for ADC to convert input waveform and display results by increment or decrements of LED's. The MCP3008 ADC clock is 1.3 MHz clock. This works and led's increment as the amplitude of the input waveform is increased from signal generator . But when i receive through UART and plot on SerialPlot , the signal is distorted please find the code for ADC below: entity ADC is port ( -- command input clock : in std_logic; -- 100MHz onboard oscillator trigger : in std_logic; -- assert to sample ADC diffn : in std_logic; -- single/differential inputs channel : in std_logic_vector(2 downto 0); -- channel to sample -- data output Dout : out std_logic_vector(14 downto 0); -- data from ADC OutVal : out std_logic; -- pulsed when data sampled -- ADC connection adc_miso : in std_logic; -- ADC SPI MISO adc_mosi : out std_logic; -- ADC SPI MOSI adc_cs : out std_logic; -- ADC SPI CHIP SELECT adc_clk : out std_logic -- ADC SPI CLOCK ); end ADC; architecture behavioural ofADC is -- clock signal adc_clock : std_logic := '0'; -- command signal trigger_flag : std_logic := '0'; signal sgl_diff_reg : std_logic; signal channel_reg : std_logic_vector(2 downto 0) := (others => '0'); signal done : std_logic := '0'; signal done_prev : std_logic := '0'; -- output registers signal val : std_logic := '0'; signal D : std_logic_vector(9 downto 0) := (others => '0'); -- state control signal state : std_logic := '0'; signal spi_count : unsigned(4 downto 0) := (others => '0'); signal Q : std_logic_vector(9 downto 0) := (others => '0'); begin -- clock divider -- input clock: 100Mhz --100MHz/1.3MHz = 74/2 -- adc clock: 1.3MHz clock_divider : process(clock) variable cnt : integer := 0; begin if rising_edge(clock) then cnt := cnt + 1; if cnt = 37 then cnt := 0; adc_clock <= not adc_clock; end if; end if; end process; -- produce trigger flag trigger_cdc : process(adc_clock) begin if rising_edge(adc_clock) then if trigger = '1' and state = '0' then sgl_diff_reg <= diffn; channel_reg <= channel; trigger_flag <= '1'; elsif state = '1' then trigger_flag <= '0'; end if; end if; end process; adc_clk <= adc_clock; adc_cs <= not state; -- SPI state machine (falling edge) adc_sm : process(adc_clock) begin if adc_clock'event and adc_clock = '0' then if state = '0' then done <= '0'; if trigger_flag = '1' then state <= '1'; else state <= '0'; end if; else if spi_count = "10000" then spi_count <= (others => '0'); state <= '0'; done <= '1'; else spi_count <= spi_count + 1; state <= '1'; end if; end if; end if; end process; -- Register sample outreg : process(adc_clock) begin if rising_edge(adc_clock) then done_prev <= done; if done_prev = '0' and done = '1' then D <= Q; Val <= '1'; else Val <= '0'; end if; end if; end process; -- LED outputs PROCESS (adc_clock) BEGIN IF (adc_clock'EVENT AND adc_clock = '1') THEN CASE D(9 DOWNTO 6) IS WHEN "0001" => Dout <= "000000000000011"; WHEN "0010" => Dout <= "000000000000111"; WHEN "0011" => Dout<= "000000000001111"; WHEN "0100" => Dout <= "000000000011111"; WHEN "0101" => Dout <= "000000000111111"; WHEN "0110" => Dout <= "000000001111111"; WHEN "0111" => Dout <= "000000011111111"; WHEN "1000" => Dout <= "000000111111111"; WHEN "1001" => Dout <= "000001111111111"; WHEN "1010" => Dout <= "000011111111111"; WHEN "1011" => Dout <= "000111111111111"; WHEN "1100" => Dout <= "001111111111111"; WHEN "1101" => Dout <= "011111111111111"; WHEN "1110" => Dout <= "111111111111111"; WHEN "1111" => Dout <= "111111111111111"; WHEN OTHERS => Dout <= "000000000000001"; END CASE; END IF; -- END IF; END PROCESS; OutVal <= Val; -- MISO shift register (rising edge) shift_in : process(adc_clock) begin if adc_clock'event and adc_clock = '1' then if state = '1' then Q(0) <= adc_miso; Q(9 downto 1) <= Q(8 downto 0); end if; end if; end process; -- Decode MOSI output shift_out : process(state, spi_count, sgl_diff_reg, channel_reg) begin if state = '1' then case spi_count is when "00000" => adc_mosi <= '1'; -- start bit when "00001" => adc_mosi <= sgl_diff_reg; when "00010" => adc_mosi <= channel_reg(2); when "00011" => adc_mosi <= channel_reg(1); when "00100" => adc_mosi <= channel_reg(0); when others => adc_mosi <= '0'; end case; else adc_mosi <= '0'; end if; end process; end behavioural; --much of the code is of credit to micronova electronics. For fifo, I use the Xilinx IP fifo generator with no FWFT working on 100Mhz clock both on write and read sides. FIFO width = 10 Depth = 2046 and tried increasing upto 131072 with no progress. This is my top level code with UART entity top_module is Generic ( PARITY_BIT : string := "none" -- type of parity ); port( clk, rst,trigger,diffn: in std_logic; adc_mosi,adc_clk,adc_cs : out std_logic; adc_miso : in std_logic; channel : in std_logic_vector ( 2 downto 0); wr_uart,uart_clk_en : in std_logic; WriteEn , ReadEn : in std_logic; full, empty : out std_logic; --w_data: in std_logic_vector(7 downto 0); Dout : inout std_logic_vector(9 downto 0); busy : out std_logic; tx,OutVal: out std_logic ); end top_module; architecture structural of top_module is signal fifo_data_out : STD_LOGIC_VECTOR (9 downto 0); component fifo is port ( reset_rtl_0 : in STD_LOGIC; clk_100MHz : in STD_LOGIC; full_0 : out STD_LOGIC; din_0 : in STD_LOGIC_VECTOR ( 9 downto 0 ); wr_en_0 : in STD_LOGIC; empty_0 : out STD_LOGIC; dout_0 : out STD_LOGIC_VECTOR ( 9 downto 0 ); rd_en_0 : in STD_LOGIC ); end component fifo; begin MercuryADC : entity work.ADC port map ( clock => clk, trigger => trigger, diffn => diffn, channel => channel, -- data output Dout => Dout, OutVal => Outval, -- ADC connection adc_miso => adc_miso, adc_mosi => adc_mosi, adc_cs => adc_cs, adc_clk =>adc_clk ); fifo_i: component fifo port map ( clk_100MHz => clk, din_0(9 downto 0) => Dout(9 downto 0), dout_0(9 downto 0) => fifo_data_out(9 downto 0), empty_0 => empty, full_0 => full, rd_en_0 => ReadEn, reset_rtl_0 => rst, wr_en_0 => WriteEn ); uart_trx : entity work.UART_TX Port map ( CLK => clk, -- system clock RST => rst, -- high active synchronous reset -- UART INTERFACE UART_CLK_EN => uart_clk_en, -- oversampling (16x) UART clock enable UART_TXD => tx, -- serial transmit data -- USER DATA INPUT INTERFACE DATA_IN =>fifo_data_out (9 downto 2) , -- input data DATA_SEND => wr_uart,-- when DATA_SEND = 1, input data are valid and will be transmit BUSY => busy -- when BUSY = 1, transmitter is busy and you must not set DATA_SEND to 1 ); end structural; PFA the schematic of my design and waveform as well. input is 650 hz and Vpp= 1.5V; continuous sine wave. My output waveform appears to be distorted. I'm not sure if there has to be a delay incorporated while sampling the input signal or a is the issue between FIFO and UART. When WriteEn signal is asserted on FIFO, the full flag is asserted at the same instant, does that mean the size of FIFO is not enough. Kindly help, any inputs will be appreciated. MCP3008(3).pdf