hamster

Members
  • Content Count

    515
  • Joined

  • Last visited

  • Days Won

    79

Everything posted by hamster

  1. hamster

    Pmod Ad5

    Oh, and you may also need to put a synchroniser on pmod_miso, as it is an async signal.
  2. hamster

    Pmod Ad5

    The easy way is to capture the MISO signal when the sclk signal is raised, and then sample the caputured bits in this register when we start the next conversion. And that should be it - now would be the time to re-read the datasheet closely, paying special attention to the registers, timing and clock speeds, verifying everything against the simulation traces, and then hit boards & logic analyzer to debug it. ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); signal cs_shift_reg : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want signal mosi_shift_reg : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want signal miso_shift_reg : std_logic_vector(63 downto 0) := (others => '0'); signal startup_timer : unsigned(9 downto 0) := to_unsigned(600,10); -- 500us at 50Mhz; signal sent_command : std_logic := '0'; begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then if startup_timer = 0 then case counter is when to_unsigned(0,6) => pmod_sclk <= '1'; -- Correct time to capture data ison the rising edge. miso_shift_reg <= miso_shift_reg(miso_shift_reg'high-1 downto 0) & pmod_miso; when to_unsigned(12,6) => -- change the CS signal when SCLK is high -- Output the highest bit and advance the shift register pmod_cs <= cs_shift_reg(cs_shift_reg'high-1); cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1'; when to_unsigned(24,6) => pmod_sclk <= cs_shift_reg(cs_shift_reg'high); when to_unsigned(37,6) => -- Output the highest bit and advance the shift register pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1); mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '0'; when to_unsigned(49,6) => if cs_shift_reg = x"FFFFFFFFFFFFFFFF" then if sent_command = '0' then -- we should have all the data bits in mosi_shift_reg, so latch it samples <= mosi_shift_reg(23 downto 0); -- send the start conversion command cs_shift_reg <= x"FF000000007FFFFF"; mosi_shift_reg <= x"0008280060000000"; sent_command <= '1'; elsif pmod_miso = '0' then -- Send the read data command cs_shift_reg <= x"FF000000007FFFFF"; mosi_shift_reg <= x"0058000000000000"; sent_command <= '0'; end if; end if; when others => NULL; end case; else -- Just during startup, output > 40 '1' bits to reset the ADC, then wait for at least 500us. pmod_mosi <= '1'; case counter is when to_unsigned(0,6) => pmod_sclk <= '1'; when to_unsigned(12,6) => if startup_timer >= 512 then pmod_cs <= '0'; end if; when to_unsigned(24,6) => if startup_timer >= 512 then pmod_sclk <= '0'; end if; when to_unsigned(49,6) => startup_timer <= startup_timer - 1; when others => NULL; end case; end if; -- Generate the 1MHz for the SPI interface -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then counter <= (others => '0'); else counter <= counter + 1; end if; end if; end process; end Behavioral;
  3. hamster

    Pmod Ad5

    So, almost there. Now we need the second half of the transaction. When cs_shift_reg is all ones, we know we have sent the request for data to the DAC. MOSI should be high until the data is ready. When MOSI drops, we need to send a "read" command (0x58) to the ADC, and then capture the output... Humm... first things first - make it flip between requesting a conversion, and then request data: ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); signal cs_shift_reg : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want signal mosi_shift_reg : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want signal startup_timer : unsigned(9 downto 0) := to_unsigned(600,10); -- 500us at 50Mhz; signal sent_command : std_logic := '0'; begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then if startup_timer = 0 then case counter is when to_unsigned(0,6) => pmod_sclk <= '1'; when to_unsigned(12,6) => -- change the CS signal when SCLK is high -- Output the highest bit and advance the shift register pmod_cs <= cs_shift_reg(cs_shift_reg'high-1); cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1'; when to_unsigned(24,6) => pmod_sclk <= cs_shift_reg(cs_shift_reg'high); when to_unsigned(37,6) => -- Output the highest bit and advance the shift register pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1); mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '0'; when to_unsigned(49,6) => if cs_shift_reg = x"FFFFFFFFFFFFFFFF" then if sent_command = '0' then -- send the start conversion command cs_shift_reg <= x"FF000000007FFFFF"; mosi_shift_reg <= x"0008280060000000"; sent_command <= '1'; elsif pmod_miso = '0' then -- Send the read data command cs_shift_reg <= x"FF000000007FFFFF"; mosi_shift_reg <= x"0058000000000000"; sent_command <= '0'; end if; end if; when others => NULL; end case; else -- Just during startup, output > 40 '1' bits to reset the ADC, then wait for at least 500us. pmod_mosi <= '1'; case counter is when to_unsigned(0,6) => pmod_sclk <= '1'; when to_unsigned(12,6) => if startup_timer >= 512 then pmod_cs <= '0'; end if; when to_unsigned(24,6) => if startup_timer >= 512 then pmod_sclk <= '0'; end if; when to_unsigned(49,6) => startup_timer <= startup_timer - 1; when others => NULL; end case; end if; -- Generate the 1MHz for the SPI interface -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then counter <= (others => '0'); else counter <= counter + 1; end if; end if; end process; end Behavioral; Next step is to capture the bits from the ADC, and move them to 'sample' at the correct time....
  4. hamster

    Pmod Ad5

    Next minor detail - the AD7193 needs to have 40 '1's written to it to trigger a reset, then wait 500us after reset to become active. It needs a bit of a major refactor of the code, into "startup" and the normal function. It also requires simulating now for 700us. As a bonus I've also implemented the first half of the transaction in figure 35. ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); signal cs_shift_reg : std_logic_vector(63 downto 0) := x"FF000000007FFFFF"; signal mosi_shift_reg : std_logic_vector(63 downto 0) := x"0008280060000000"; signal startup_timer : unsigned(9 downto 0) := to_unsigned(600,10); -- 500us at 50Mhz; begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then if startup_timer = 0 then case counter is when to_unsigned(0,6) => pmod_sclk <= '1'; when to_unsigned(12,6) => -- change the CS signal when SCLK is high -- Output the highest bit and advance the shift register pmod_cs <= cs_shift_reg(cs_shift_reg'high-1); cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1'; when to_unsigned(24,6) => pmod_sclk <= cs_shift_reg(cs_shift_reg'high); when to_unsigned(37,6) => -- Output the highest bit and advance the shift register pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1); mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '1'; when others => NULL; end case; else -- Just during startup, output > 40 '1' bits to reset the ADC, then wait for at least 500us. pmod_mosi <= '1'; case counter is when to_unsigned(0,6) => pmod_sclk <= '1'; when to_unsigned(12,6) => if startup_timer >= 512 then pmod_cs <= '0'; end if; when to_unsigned(24,6) => if startup_timer >= 512 then pmod_sclk <= '0'; end if; when to_unsigned(49,6) => startup_timer <= startup_timer - 1; when others => NULL; end case; end if; -- Generate the 1MHz for the SPI interface -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then counter <= (others => '0'); else counter <= counter + 1; end if; end if; end process; end Behavioral;
  5. hamster

    Pmod Ad5

    So here's my first error, readying page 34, SCLK should be high when idle, as this lowers the noise and power. So here are some minor tweaks to get it all looking correct in the simulation ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); signal cs_shift_reg : std_logic_vector(63 downto 0) := x"FF007FFFFFFFFFFF"; signal mosi_shift_reg : std_logic_vector(63 downto 0) := x"00A5000000000000"; begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then -- First off, generate a 1MHz square wave for SCLK; -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then pmod_sclk <= '1'; counter <= (others => '0'); else -- change the CS signal when SCLK is high if counter = 12 then -- Output the highest bit and advance the shift register pmod_cs <= cs_shift_reg(cs_shift_reg'high-1); cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1'; end if; if counter = 24 then pmod_sclk <= cs_shift_reg(cs_shift_reg'high); end if; if counter = 37 then -- Output the highest bit and advance the shift register pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1); mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '1'; end if; counter <= counter + 1; end if; end if; end process; end Behavioral;
  6. hamster

    Pmod Ad5

    Great - if you get this far, you should be able to fire up the simulator and get a trace which shows CLK50MHz running at 50Mhz, and PMOD_SCLK running at 1MHz. However, I've run out of space to upload images, so can't show you :-(. So trust me - you now have a 1MHz SCK. Next is to start sending data out. I2S send in MSB first. so source reads best if we send bits from high to low. To do this we need a shift register, and to output the highest bit from it at the correct time: ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); signal cs_shift_reg : std_logic_vector(63 downto 0) := x"FF007FFFFFFFFFFF"; begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then -- First off, generate a 1MHz square wave for SCLK; -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then pmod_sclk <= '1'; counter <= (others => '0'); else -- change the CS signal when SCLK is high if counter = 12 then -- Output the highest bit and advance the shift register pmod_cs <= cs_shift_reg(cs_shift_reg'high); cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1'; end if; if counter = 24 then pmod_sclk <= '0'; end if; counter <= counter + 1; end if; end if; end process; end Behavioral; In simulation I now get a PMOD_CS that drops when the SCLK signal is high, and stays low for 9us (or 9 clock cycles) due to the data in the cs_shift_reg. Now to the the same to the data line, but this time the data has to change in the middle of the low part of the clock cycle ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); signal cs_shift_reg : std_logic_vector(63 downto 0) := x"FF00FFFFFFFFFFFF"; signal mosi_shift_reg : std_logic_vector(63 downto 0) := x"00A5000000000000"; begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then -- First off, generate a 1MHz square wave for SCLK; -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then pmod_sclk <= '1'; counter <= (others => '0'); else -- change the CS signal when SCLK is high if counter = 12 then -- Output the highest bit and advance the shift register pmod_cs <= cs_shift_reg(cs_shift_reg'high); cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1'; end if; if counter = 24 then pmod_sclk <= '0'; end if; if counter = 37 then -- Output the highest bit and advance the shift register pmod_mosi <= mosi_shift_reg(mosi_shift_reg_shift_reg'high); mosi_shift_reg_shift_reg <= mosi_shift_reg_shift_reg(mosi_shift_reg_shift_reg'high-1 downto 0) & '1'; end if; counter <= counter + 1; end if; end if; end process; end Behavioral; When you simulate that you should get something that looks like the SPI transfer on page 9 of the datasheet. (I just picked 'A5' as a pleasing bit pattern to send out, so I can see where the transitions are relative to the other signals) Time for me to read some more of the data sheet....
  7. hamster

    Pmod Ad5

    Hi 1116345, So here is a quick hack at it, without any reference to the datasheet. First off you need an idea of what the interface design for the AD5 will look like - here's my stab at it: - COMPONENT pmod_ad5 PORT( clk50MHz : IN std_logic; pmod_sclk : OUT std_logic; pmod_mosi : OUT std_logic; pmod_miso : IN std_logic; pmod_cs : OUT std_logic; samples : OUT std_logic_vector(23 downto 0) ); END COMPONENT; The 50 MHz system clock, the PMOD signals, and something to hold the sample. And now here's the first file of VHDL - it does nothing but divide the system clock from 50 MHz down to 1 MHz, for use as the SPI clock: ---------------------------------------------------------------------------------- -- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pmod_ad5 is Port ( clk50MHz : in STD_LOGIC; pmod_sclk : out STD_LOGIC := '1'; pmod_mosi : out STD_LOGIC := '1'; pmod_miso : in STD_LOGIC; pmod_cs : out STD_LOGIC := '1'; samples : OUT std_logic_vector(23 downto 0) ); end pmod_ad5; architecture Behavioral of pmod_ad5 is signal counter : unsigned(5 downto 0) := (others => '0'); begin p: process(clk50Mhz) begin if rising_edge(clk50MHz) then -- First off, generate a 1MHz square wave for SCLK; -- I haven't checked how fast the SPI interface works, so check this on the datasheet. if counter = 49 then pmod_sclk <= '1'; counter <= (others => '0'); else if counter = 24 then pmod_sclk <= '0'; end if; counter <= counter + 1; end if; end if; end process; end Behavioral; You will also need to add a constraints file (.UCF file) to attach the external signals to the correct pins. For testing you might want to connect the highest 8 bits of 'samples' to the LEDs. You will also need a test bench to allow you to simulate the design: -------------------------------------------------------------------------------- -- TB_PMOD_AD5 - test bench for my attempt at using the PMODAD5 -------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY tb_pmod_ad5 IS END tb_pmod_ad5; ARCHITECTURE behavior OF tb_pmod_ad5 IS COMPONENT pmod_ad5 PORT( clk50MHz : IN std_logic; pmod_sclk : OUT std_logic; pmod_mosi : OUT std_logic; pmod_miso : IN std_logic; pmod_cs : OUT std_logic; samples : OUT std_logic_vector(23 downto 0) ); END COMPONENT; signal clk50MHz : std_logic := '0'; signal pmod_miso : std_logic := '0'; signal pmod_sclk : std_logic; signal pmod_mosi : std_logic; signal pmod_cs : std_logic; signal samples : std_logic_vector(23 downto 0); -- Clock period definitions constant clk50MHz_period : time := 20 ns; BEGIN uut: pmod_ad5 PORT MAP ( clk50MHz => clk50MHz, pmod_sclk => pmod_sclk, pmod_mosi => pmod_mosi, pmod_miso => pmod_miso, pmod_cs => pmod_cs ); clk50MHz_process :process begin clk50MHz <= '0'; wait for clk50MHz_period/2; clk50MHz <= '1'; wait for clk50MHz_period/2; end process; END;
  8. hamster

    Pmod Ad5

    Hi i1116345, From a quick read of the datasheet, it seems that you need to send a few register writes to switch ADC into continuous sample mode, and then you can just clock the data in every time DRDY is asserted. You can take either the high road (with lots of levels of abstractions in your design) or the often-muddy low road (where you do all the work on paper, and then just make a design that achieves the desired result). The high road most likely involves a soft CPU, with a SPI peripheral interface, and software that talks SPI that will configure the device and retrieve the samples. The low road involves a long shift register to send out the SPI signals needed to configure the eight registers in the device, and then a simple FSM that clocks in the samples when they are available, storing the values into a flip-flops connected to the LEDs. So to me the low road looks to be something like two or three 128-bit shift registers (as it has to program up to eight 8-bit registers), a counter to act as a clock divider, and a small FSM that clocks in the samples . I know which road I would take - but that is just me. Mike
  9. hamster

    Nexys4 Board.

    I was Interested to see the Nexys4 DDR board appearing the the "Coming soon" category (http://www.digilentinc.com/Products/Detail.cfm?Prod=NEXYS4DDR) Makes me sad to see the old boards going End Of Life, especially since the Nexys3 and Nexys4 are relatively new products.
  10. Hi, I've hauled my PMOD I2S out of the cupboard, and got it going on my Basys3, under Vivado First, the I2S interface ---------------------------------------------------------------------------------- -- Engineer: Mike Field <hamster@snap.net.nz> -- -- Description: Generate I2S audio stream ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; Library UNISIM; use UNISIM.vcomponents.all; entity i2s_output is Port ( clk : in STD_LOGIC; -- Interface to the source of the audio data_l : in STD_LOGIC_VECTOR (15 downto 0); data_r : in STD_LOGIC_VECTOR (15 downto 0); data_accepted : out STD_LOGIC; -- Interface out to the DAC i2s_sd : out STD_LOGIC; i2s_lrclk : out STD_LOGIC; i2s_sclk : out STD_LOGIC; i2s_mclk : out STD_LOGIC); end i2s_output; architecture Behavioral of i2s_output is signal step : unsigned(8 downto 0) := (others => '0'); signal shift_out : std_logic_vector(16 downto 0) := (others => '0'); signal hold_r : std_logic_vector(15 downto 0) := (others => '0'); begin -- Set the output signals i2s_lrclk <= std_logic(step(8)); i2s_sclk <= std_logic(step(3)); i2s_sd <= shift_out(shift_out'high); mclk_ODDR: ODDR generic map( DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE" INIT => '0', -- Initial value for Q port ('1' or '0') SRTYPE => "SYNC") -- Reset Type ("ASYNC" or "SYNC") port map ( Q => i2s_mclk, -- 1-bit DDR output C => clk, -- 1-bit clock input CE => '1', -- 1-bit clock enable input D1 => '1', -- 1-bit data input (positive edge) D2 => '0', -- 1-bit data input (negative edge) R => '0', -- 1-bit reset input S => '0' -- 1-bit set input ); process(clk) begin if rising_edge(clk) then -- Default to telling the source to wait data_accepted <= '0'; if step = "111111111" then -- start sending the left sample, and signal the source -- that we have started sending both channels shift_out(15 downto 0) <= data_l; hold_r <= data_r; data_accepted <= '1'; elsif step = "011111111" then -- switch to sending the right sample shift_out(15 downto 0) <= hold_r; elsif step(3 downto 0) = "1111" then -- Just send the next bit. shift_out <= shift_out(shift_out'high-1 downto 0) & '1'; end if; step <= step + 1; end if; end process; end Behavioral; Second, the top level source library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity i2s_test_top is Port ( clk100 : in STD_LOGIC; -- Interface out to the DAC JA : out std_logic_vector(3 downto 0)); end i2s_test_top; architecture Behavioral of i2s_test_top is component i2s_output is Port ( clk : in STD_LOGIC; -- Interface to the source of the audio data_l : in STD_LOGIC_VECTOR (15 downto 0); data_r : in STD_LOGIC_VECTOR (15 downto 0); data_accepted : out STD_LOGIC; -- Interface out to the DAC i2s_sd : out STD_LOGIC; i2s_lrclk : out STD_LOGIC; i2s_sclk : out STD_LOGIC; i2s_mclk : out STD_LOGIC); end component; signal clk : std_logic := '0'; signal toggle : std_logic := '0'; signal accepted : std_logic; signal data : STD_LOGIC_VECTOR (15 downto 0) := x"C000"; signal count : unsigned(7 downto 0) := (others => '0'); begin i_output: i2s_output Port map ( clk => clk, -- Interface to the source of the audio data_l => data, data_r => data, data_accepted => accepted, i2s_mclk => ja(0), i2s_lrclk => ja(1), i2s_sclk => ja(2), i2s_sd => ja(3) ); p_clk: process(clk) begin if rising_edge(clk) then if accepted = '1' then if count = 99 then count <= (others => '0'); data(15) <= not data(15); else count <= count + 1; end if; end if; end if; end process; p_clk100: process(clk100) begin if rising_edge(clk100) then if toggle = '1' then clk <= not clk; end if; toggle <= not toggle; end if; end process; end Behavioral; Third, the constraints: ## Clock signal set_property PACKAGE_PIN W5 [get_ports clk100] set_property IOSTANDARD LVCMOS33 [get_ports clk100] create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk100] ##Pmod Header JA #Sch name = JA1 set_property PACKAGE_PIN J1 [get_ports {JA[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {JA[0]}] set_property PACKAGE_PIN L2 [get_ports {JA[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {JA[1]}] set_property PACKAGE_PIN J2 [get_ports {JA[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {JA[2]}] set_property PACKAGE_PIN G2 [get_ports {JA[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {JA[3]}] As it is running at 25Mhz, and using a 512 clocks per frame the audio rate will be 48,828 samples per second. As the top level module drives it with a square wave taking 200 sample, it should be a buzz of 244.14Hz: It looks quite noise, but that is actually because of the filtering on the edges - they contain no frequencies over 24kHz or so and so they 'ring' a little:
  11. Don't give up just yet - just try replacing NET "ld[1]" LOC = "p14" ; with NET "ld<1>" LOC = "M11"; And see if one of your errors goes away! The reason is that the Basys2 doesn't have a pin named P14.... that signal is connected to the pin named M11.
  12. I did a quick Google, and it looks like you are using the constraints file for the original Basys board. So I've grabbed the master constraint file for the Basys2 from http://www.digilentinc.com/Products/Detail.cfm?Prod=BASYS2 You should be using the following lines NET "ld<1>" LOC = "M11" ; # Bank = 2, Signal name = LD1 NET "ld<0>" LOC = "M5" ; # Bank = 2, Signal name = LD0 NET "sw<3>" LOC = "B4"; # Bank = 3, Signal name = SW3 NET "sw<2>" LOC = "K3"; # Bank = 3, Signal name = SW2 NET "sw<1>" LOC = "L3"; # Bank = 3, Signal name = SW1 NET "sw<0>" LOC = "P11"; # Bank = 2, Signal name = SW0
  13. The most likely cause for this is that you have the wrong device and/or package selected for your FPGA board. Right-click on the top level of your project and select properties. Make sure that the Device Is XC3S100E or XC3S250E and that the package is set to CP132. It should look something like If this doesn't fix it, can you post a screenshot of your design's properties?
  14. Comment out or delete all the unused lines - you should only have those that your design uses. There is a synthesis option that makes these errors into warnings , but if you use it you will regret it! You will spend a night trying to track why a design does work only to find a signal called 'LEDs' in you HDL is called 'LED' in your UCF file, and a warning has been trying to tell you that all night.
  15. http://hamsterworks.co.nz/mediawiki/index.php/Pmodi2s
  16. What values are you sending to the DAC? All ones and all zero? Been there done that..... A square wave of 0000 and FFFF (0 and -1) is quite quiet. Try 0x4000 and 0xC000. It will be at 50% regardless of any signed/unsigned issues.
  17. hamster

    Basys �

    just to close the thread off - I've been communicating with email, and issues with the design that Gustavo345 faced were... 1) The project was not set to the correct device, so it wouldn't build correctly. 2) The last change in the code was to speed things to a sensible PWM frequency. The counter was reduced to 20 bits (0 -> 1,048,575), but in Gustavo345's design the constants were still left at 9,999,999, 5,000,000 and so on. As all the comparisons became constant.everything gets optimised away. Cheers Mike
  18. Yes. Most servos are specified at a V+ of 4.8V, and need a TTL level signal for the control pulse. Logic high for a TTL signal is around 2V. This means that any I/O pin that can drive a LVTTL signal will work, but be careful - if you short the V+ voltage to the signal pin you might fry your FPGA. This makes it worth-while to put a 100 Ohm resistor in series to lower any fault current that can occur to a few milliamps. Digilent have a PMOD that is designed for using with RC servos - PMOD-CON3. If you look at the schematic in the reference manual (http://www.digilentinc.com/Data/Products/PMOD-CON3/Pmod%20Con3_rm.pdf) you will see how simple the connection is.
  19. The protocol interface is pretty simple - the state of the bus has to be reset by holding the data signal low for 50us, followed with sending out 24 bits for each LED that is connected in the string. The '1' bits are sent by driving the data line high for 0.9us, followed by driving the line low for 0.35ns, The '0' bits are sent by driving the line high for 0.35us, then driving it low for 0.90us. The frame is in 8-bit Green, then 8-bit Red then 8-bit Blue format, and within each colour the MSB is sent first. Once they have received a 24-bit colour value the LED will remember it until a new colour is received (or power removed). The timing is quite tight. If you are writing your own code for a micro-controller you will definitely want to have interrupts disabled while you bit-bash your bits (as servicing an interrupt might cause a glitch). If you want to get started with an FPGA you can find some source at http://hamsterworks.co.nz/mediawiki/index.php/Intelligent_LEDs Oh, and they can suck a lot of juice - each LED can use up to 0.3W - it only takes 15 LEDs to overload a USB port!
  20. Some simple Google-fu like "WS2812B filetype:pdf" gives the following links: If the LEDs have 6 pins then they are the older WS2812 model : https://www.adafruit.com/datasheets/WS2812.pdf If the LEDs have 4 pins then they are the new WS2812B model : http://www.adafruit.com/datasheets/WS2812B.pdf And what is the difference (apart from the number of pins?) : http://www.lightingnext.com/WS2812B_VS_WS2812.pdf
  21. hamster

    Basys �

    Have you set the Device and Package settings correctly (for your board)? Does it now work?
  22. Well that is the correct constraint for a pin on JC. Are you sure you are measuring it correctly? What HDL code are you using to test the pin with?
  23. hamster

    Basys �

    Well, it the pin locations are invalid in your project, then you must have the wrong Package setting for your project. It should look like this: Also note that this is for a Basys2-250 - for a Basys2-100 the device will be XC3S100E.
  24. hamster

    Basys �

    Hi Gustavo345, Actually posting the error text that is causing the build to stop would be more helpful than installing an older version of ISE, so I/we don't have to guess at your problem is and can guide you appropriately.Having said that, here is my guess at your problem... One of the most common issues that people have with their first project is they select either the wrong FPGA or package type - it is not like with CPUs where the program will run on any CPU of the same processor architecture. The top level of your project (in the "Hierarch" window) should show "xc3s250e-5cp132" for a Basys2-250 or "xc3s100e-5cp132" for the Basys2-100. If ti doesn't, right-click on it, choose properties, and correct the wrong setting. Mike PS. I think I might actually have the wrong speed grade in there (-5 vs -4), but that won't really matter for such a simple project,..
  25. Does the signal have either an external pull up resistor, have you added the PULLUP contstraint on that pin or added a PULLUP primitive to the output signal?