hamster

Members
  • Content count

    410
  • Joined

  • Last visited

  • Days Won

    70

hamster last won the day on June 14

hamster had the most liked content!

About hamster

  • Rank
    Overly helpful
  • Birthday 08/23/1969

Contact Methods

  • Website URL
    http://hamsterworks.co.nz

Profile Information

  • Gender
    Male
  • Location
    New Zealand
  • Interests
    Electronics, FPGAs, MtBiking, Road Cycling, Linux....

Recent Profile Visitors

3,088 profile views
  1. For the definitive word on how to infer memory blocks, including code examples, have a look at https://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_1/ug901-vivado-synthesis.pdf from page 95. It covers everything from the simplest single port RAMs/ROMs to dual port RAMs with different data widths, with byte enables. For the large part, the same patterns also work in ISE. page 148 & 149 might be of special interest. It has "Initializing Block RAM From an External Data File VHDL Coding Example" and "Initializing Block RAM From an External Data File Verilog Coding Example"
  2. Hi! I too share your pain :-) I now infer all my ROMs - using code like this: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity beacon is Port ( clk : in STD_LOGIC; leds : out STD_LOGIC_VECTOR (7 downto 0)); end beacon; architecture Behavioral of beacon is type a_data is array(0 to 31) of std_logic_vector(7 downto 0); signal data : a_data := ( x"01",x"02",x"04",x"08",x"10",x"20",x"40",x"80", x"01",x"02",x"04",x"08",x"10",x"20",x"40",x"80", x"01",x"01",x"02",x"02",x"04",x"04",x"08",x"08", x"10",x"10",x"20",x"20",x"40",x"40",x"80",x"80"); signal counter : unsigned(26 downto 0) := (others => '0'); begin process(clk) begin if rising_edge(clk) then leds <= data(to_integer(counter(counter'high downto counter'high-4))); counter <= counter+1; end if; end process; end Behavioral; This is something I had open right now - the counter is longer than it would need to be for a ROM address, passed in as a parameter for the module. It isn't very much work to make a script that converts your source data (in whatever format) into the entire Verilog/VHDL module, and it means that your code will work with other FPGA vendors tooling. If you track down some Arcade Game implementations for an FPGA they usually have a script to do exactly this - it is against the rules to include the ROM dumps in the code base. For example - https://github.com/bhamadicharef/bombjack-papilioplus-fpga/tree/master/romgen_source
  3. HI, This is a case when using shift registers can make your life so much easier in the constants - you can almost draw what you want to see library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity dac is Port ( clk : in STD_LOGIC; dac_clk : out STD_LOGIC; dac_cs : out STD_LOGIC; dac_ld : out STD_LOGIC; dac_data : out STD_LOGIC); end dac; architecture Behavioral of dac is signal clk_sr : std_logic_vector(3 downto 0) := "0011"; signal cs_sr : std_logic_vector(19 downto 0) := x"C0003"; signal data_sr : std_logic_vector(19 downto 0) := x"00000"; signal ld_sr : std_logic_vector(19 downto 0) := x"FFFFE"; signal counter : unsigned(2 downto 0) := "000"; type t_table is array(0 to 7) of std_logic_vector(15 downto 0); signal table : t_table := ( x"8000",x"E000",x"FFFF",x"E000", x"8000",x"2000",x"0000",x"2000"); begin process(clk) begin if rising_edge(clk) then -- Set the outputs dac_clk <= clk_sr(clk_sr'high); dac_cs <= cs_sr(cs_sr'high); dac_data <= data_sr(data_sr'high); dac_ld <= ld_sr(ld_sr'high); -- shift the data shift registers if clk_sr = "1001" then cs_sr <= cs_sr(cs_sr'high-1 downto 0) & cs_sr(cs_sr'high); data_sr <= data_sr(data_sr'high-1 downto 0) & data_sr(data_sr'high); ld_sr <= ld_sr(ld_sr'high-1 downto 0) & ld_sr(ld_sr'high); -- put a new data value in the data shift register, when needed needed if cs_sr(15) = '1' and cs_sr(14) = '0' then data_sr(15 downto 0) <= table(to_integer(counter)); counter <= counter + 1; end if; end if; -- Shift the clock shift registers clk_sr <= clk_sr(clk_sr'high-1 downto 0) & clk_sr(clk_sr'high); end if; end process; end Behavioral; I've attached the simulation image
  4. Hi! I've hooked up a CMOD-A7 to an audio codec board designed for the Raspberry Pi, getting ready to play with some audio. You can find the VHDL source at http://hamsterworks.co.nz/mediawiki/index.php/STGL5000#sgtl5000_interface.vhd It is still rough and ready, but it works
  5. The SERDES isn't super tricky to use once working (esp for outputs), but getting it to work the first time is quite hard. Make sure that you follow the clocking design in the user guide exactly. You don't have the flexibility to use just any clocking resource to drive them - you must use the correct MMCM connections and the correct buffers The bit ordering can be a confusing, when thinking about the order of the bits on the wire. In the user guide there is a picture that is helpful, showing the order the bits leave the SERDES block and then arrive at the receiver. The spec sheet limits performance to about 1Gb/s or 1.25Gb/s (for a 500 or 600 MHz toggle rate). They can work a little bit faster than this, but of course that is out of spec.
  6. Hi! Is the USB stick formatted with FAT32? I have had no problem with loading a bit file from a USB stick on my Basys3... except when it was formatted with NTFS ;-)
  7. Hi deltaepsilon3, You can talk directly to the Ethernet interfaces - here is something for the Arty Board, showing the level of complexity needed http://hamsterworks.co.nz/mediawiki/index.php/ArtyEthernet For Gigabit Ethernet it is much the same http://hamsterworks.co.nz/mediawiki/index.php/GigabitTX With a bit of experimentation you can replace the data payload with your samples, and implement some form of flow control (so you only send packets when you have data to send. Mike
  8. At a glance, from the last screen shot it seems you are sampling 10 channels, so that look to be about 100k samples per channel per second... I haven't used the XADC that much at all. You would really need to have a a quick read of the user guide to find the bits of interest, then read them closely to find out exactly what you want to do. Mike
  9. This little module might be of use to somebody - it sends 16-bit values to an external serial device, as four ascii hexidecimal digits (eg "12AB"), with new lines and carriage returns. http://hamsterworks.info/index.php/Hw_tx_binary_as_ascii The sample design send the settings of the 16 slide switches every time the center button is pressed.
  10. The XADC is a Dual 12-bit ADC. 1MS/s ADC. You are you getting the data off of the ARTY for analysis? Or are you using a Microblaze CPU? Are you getting 1,000,000 reading per second? The ADCs are shared between multiple channels, so if you have 5 channels enabled you will at best only get 200k samples per channel. It can also be set up as bipolar or unipolar mode - are you sure you have it configured right? can you show any of your configuration? For unipolar signals the XADC's range is only from 0.0V to 1.0V - are you sure you are not driving it out of this range?
  11. A few reasons are... a - The introduction of logic hazards can cause glitches : https://en.wikipedia.org/wiki/Hazard_(logic) b - Routing of clocks is very complex - It is hard to ensure that the same clock edge appears all over the FPGA at almost exactly the same time. Sometimes this is achieved with 'slight of hand' (e.g. using a on-chip PLL to advance phase of the clock, so that by the time it reaches the edge of the chip is in back phase with the original signal). Low-skew paths also exist, but are restricted to small areas of the FPGA, and the clock has to be connected to the correct pin to be placed and routed correctly. c - FPGAs and their tools are designed to behave predictably under the "synchronous digital design" paradigm (something like https://hps.hs-regensburg.de/scm39115/homepage/education/courses/red/2_SynchronousDigitalCircuitDesignRules.pdf). If you work outside the paradigm you will be fighting against the tools and their assumptions. d - There is almost nothing that you are unable to code in an FPGA friendly way, but there are infinitely many ways to write FPGA-hostile code. If you want your FPGA to place nice with you, you have to play nice with it. So you can either add an RC filter to debounce you switch, or you can sample it using a reliable clock.
  12. I know this sounds wrong, but.... A good way to convert 8-bit binary into Decimal Digits is most likely a 256 entry lookup table, giving an two 4-bit results. Yes, it will seem a lot of code, but it will implement very efficient, is fast, and will use very little power. You can also replace a lot of logic, if your conversion would otherwise involve constants (e.g. if you also need to calculate "out_val = k * in_val + c", like you would to convert degrees C into degrees F)
  13. It does look a little odd. It looks as though it will move bits into data_reg every cycle that "spi_clk" is high, TRANSCIEVE: process(clk) begin if rising_edge(clk) if slave_select = '0' then -- slave is selected if spi_clk_tick = '1' and spi_clk_tick_last = '0' then -- seen the rising edge on spi_clk, so grab the data data_reg <= data_reg(6 downto 0) & mosi_sync; end if; end if; -- remember the current spi_clk_tick signal so we can detect if it -- changes from '0' to '1' in the next cycle spi_clk_tick_last <= spi_clk_tick; end if; end process;
  14. A while ago there was a thread about writing a 'combination lock' design for an FPGA board. I finally got around to updating my Wiki with the design: http://hamsterworks.co.nz/mediawiki/index.php/Combination_Lock A short video of it in action is here:
  15. When I get this it is usually the uppercase/lowercase of the top level signals doens't match those used in the .XDC file. This is the only place case matters in a VHDL project!