hamster

Members
  • Content Count

    515
  • Joined

  • Last visited

  • Days Won

    79

Everything posted by hamster

  1. hamster

    3 bit output

    Hi, Also, rather than assigning "---" or "XXX" when an unknown switch setting is selected, why not just assign a constant value. Assigning "don't care" or "unknown" all seems a bit none-deterministic me, and open to simulation/implementation mismatches - and those sort of bugs really hurt when they bite. Mike
  2. I've now added the checksum calculations, and going "full noise" it sends 130,000 packets per second
  3. hamster

    PWM

    Hi again, I just tried this out on an Basys3 - (Artix7-35 grade 1C) and it meets timing just - 0.008 ns slack at 3.3ns clock. The limiting thing was the length of the carry chain in the 20-bit adder. That can be broken into two shorter adders, that run faster. However, it is pretty hard to do it without getting bugs - hopefully I've got it right here: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Generic_PWM_x1 is port( clk: in std_logic; pwm_var: in std_logic_vector(19 downto 0); pwm_out: out std_logic ); end Generic_PWM_x1; architecture Behavioral of Generic_PWM_x1 is signal counter : unsigned(19 downto 0):= (others=>'0'); signal pwm_latch : unsigned(19 downto 0):= (others=>'0'); constant max_counter: unsigned(19 downto 0):= (others=>'1'); signal carry_next : std_logic := '0'; begin process(clk) begin if rising_edge(clk) then ------------------------------------------- -- Drop the output when the counter = PWM level -- Enable the output when count is zero -- Note the special ordering to ensure always off when pwm_var = 0 -- Use only absolute comparisons so no math is involved. ------------------------------------------- if counter = pwm_latch then pwm_out<='0'; elsif counter = 0 then pwm_out<='1'; end if; ------------------------------------------- -- Update the counter, but splitting the carry chain -- into an 11-bit and 9-bit adder ---------------------------------------------------- if counter=max_counter then counter <=(others=>'0'); carry_next <= '0'; pwm_latch <= unsigned(pwm_var); else counter(10 downto 0) <= counter(10 downto 0)+1; if carry_next = '1' then counter(19 downto 11) <= counter(19 downto 11) + 1; end if; if counter(10 downto 0) = "11111111110" then carry_next <= '1'; else carry_next <= '0'; end if; end if; end if; end process; end Behavioral; That just meets timing at 333 MHz (3.0 ns).
  4. hamster

    PWM

    What have you constrained the clock to? The more it is constrained the harder the tools will work to give you a faster design. What timing are you getting? Sorry about the missing 'then' in the code above too!
  5. hamster

    PWM

    Oh, the other option is to use a DDR output, and generate two output bits per cycle, allowing a 150 MHz design can generate 300 Mb/s. This is a pretty generic technique - using the serializers you can generate about 1Gb/s running the design on a 125 MHz clock!
  6. hamster

    PWM

    Hi, This might give you some ideas, it should be about the fastest you can achieve.. begin if rising_edge(clk) then ------------------------------------------- -- Drop the output when the conter = PWM level -- Enable the output when count is zero -- Note the special ordering to ensure always off when pwm_var = 0 -- Use only absolute comparisons so no math is involved. ------------------------------------------- if counter = pwm_var then pwm_out<='0'; elsif counter = 0 pwm_out<='1'; end if; ------------------------------------------- -- Update the counter ------------------------------------------- if counter=max_counter then counter<=(others=>'0'); else counter <= std_logic_vector( unsigned(counter) + 1 ); end if; end if; end process; In general, if you want to generate an 'always on' output when pwm_var is all ones, then max_counter = has to be initialized to "(0=>'0', others => '1')" .e.g. "11111110" for an 8-bit counter. Oh, and things can go wrong if pwm_var is changed at the wrong time - best of to latch it into a local signal at the same time that max_counter is reset back to zeros.
  7. Hi, I've got my Arty sending out UDP packets to my laptop, without any soft CPU involvement. I've still got to add checksums and so on, but at least it works! http://hamsterworks.co.nz/mediawiki/index.php/ArtyEthernet
  8. Hi! That sounds really odd - if it was broken I would expect something other than almost 3V exactly What test point / pin are you measuring on? Do you have anything connected to the board? I'll measure it on my Arty at home....
  9. Hi! The problem is this: ERROR: [DRC 23-20] Rule violation (UCIO-1) Unconstrained Logical Port - 1 out of 5 logical ports have no user assigned specific location constraint (LOC). This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all pin locations. This design will fail to generate a bitstream unless all logical ports have a user specified site LOC constraint defined. To allow bitstream creation with unspecified pin locations (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks UCIO-1]. NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run. Problem ports: CLK. You have not defined which pin the CLK signal is being supplied on. If you add that to your .constraints ("xdc") file you should have more luck. Mike
  10. hamster

    verilog UART

    Hi SAYALI, The warning is there for exactly the reason they state: The code assigns a value to these signals, but the values they hold are never used. The fix would be to decide if they really are needed at all, and if not then remove the two signals (and all assignments to them). Mike
  11. Hi Manu, Without the code I can't offer any advice apart from maybe you should copy the serial port output to a pin on a PMOD and look at it with a scope or logic analyser. That way you can at least be sure that the input to your logic is correct or not. However, it is more than likely some subtle timing issue going on. If you are really stuck, post your code and I'll have a look at it.... Mike
  12. Well, for a start, nothing in there looks to be clocked at all. Without using a clock somewhere, you can't update any internal state.
  13. Oh, and in the test bench this looks a little off: constant clock_period : time := 40 ns; --50MHz 40 ns isn't 50 MHz
  14. Hi Jaiko07 What is specification for your output that you are aiming for? It is is a 50% duty cycle, 200Hz signal then this might be a better pattern to follow for your process: countClock: process(clock,clear) begin if (clear = '1') then adjfreq <= "000000000000000000"; elsif(clock'event and clock = '1') then -- Flip a the output once every 125,000 cycles (400Hz) -- to give a 200Hz output with 50% duty cycle if (adjfreq = "011110100001001000") then adjfreq <= "000000000000000000"; adjclock <= not adjclock; else adjfreq <= adjfreq+1; end if; end if; end process; I haven't compiled it or tested it, but the intent should be clear - you are counting the cycles between the transitions, then flipping the output.
  15. Hi Shruthi, 1) check http://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf page 60 - table 4-4. The channel numbering is a little bit odd. 2) Not sure, as XADC is only available on 7-Series FPGAs. I guess it is for future chips, and I guess it only matters for simulation. 3) If you want to only read channel 6, yes. See figure 3-1 on page 36. Mike
  16. hamster

    basys 3 FPGA

    Hi Marco you can find a very basic example of the logic for PWM control here: http://hamsterworks.co.nz/mediawiki/index.php/XADC_Fan_PWM - it controls the speed of the fan on the Genesys2 board.
  17. Oh, and just to rant on a little more. It seems to be nicer as a single "read or write" process, than two separate processes. read_and_write: process (Clock) begin if rising_edge(Clock) then if Reset = '1' then -- Synchronous reset to clear memory Memory <= (others => (others => '0')); DataOut <= (others => '0'); elsif Enable = '1' then if WriteEn = '1' then -- Write Memory Memory(to_integer(unsigned(Address))) <= DataIn; else -- Read Memory DataOut <= Memory(to_integer(unsigned(Address))); end if; end if; end if; end process;
  18. Fixups were.... Only one process should write to 'memory' (that was what was most likely breaking it - I was scratching my head as to why it was broken). In the testbench, the 'generics' were not being used correctly. Also, the middle processes (stim_main) was not needed, and was upsetting the simulation. Oh, I would tend to write the test process as: -- Stimulate Write process stim_write_read : process begin wait until rising_edge(clock); wait until rising_edge(clock); wait until rising_edge(clock); -- write Address <= "00000"; Reset <= '0'; for i in 0 to 2 loop WriteEn <= '1'; Enable <= '1'; wait until rising_edge(clock); Address <= Address + 4; DataIn <= DataIn + 3; end loop; -- read Address <= "00000"; for k in 0 to 2 loop WriteEn <= '0'; Enable <= '1'; wait until rising_edge(clock); Address <= Address + 4; end loop; Enable <= '1'; wait; end process; end; I find waiting for the clock edge makes more sense than waiting for the clock period.
  19. Contrast with this: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; entity RAM is Generic ( DATA_WIDTH : integer := 8; ADDRESS_WIDTH : integer := 8 ); Port ( Clock : in STD_LOGIC; Reset : in STD_LOGIC; DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); Address : in STD_LOGIC_VECTOR (ADDRESS_WIDTH - 1 downto 0); WriteEn : in STD_LOGIC; Enable : in STD_LOGIC; DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0) ); end RAM; architecture Behavioral of RAM is type Memory_Array is array (0 to (2 ** ADDRESS_WIDTH) - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); signal Memory : Memory_Array; begin -- Read process process (Clock) begin if rising_edge(Clock) then if Enable = '1' then if WriteEn = '0' then -- Read Memory DataOut <= Memory(to_integer(unsigned(Address))); end if; end if; end if; end process; -- Write process process (Clock) begin if rising_edge(Clock) then if Reset = '1' then -- Clear Memory on Reset Memory <= (others => (others => '0')); elsif Enable = '1' then if WriteEn = '1' then -- Store DataIn to Current Memory Address Memory(to_integer(unsigned(Address))) <= DataIn; end if; end if; end if; end process; end Behavioral; and LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY TB_RAM IS END TB_RAM; ARCHITECTURE behavior OF TB_RAM IS COMPONENT RAM Generic ( DATA_WIDTH : integer := 8; ADDRESS_WIDTH : integer := 5 ); PORT( Clock : IN std_logic; Reset : IN std_logic; DataIn : IN std_logic_vector(DATA_WIDTH-1 downto 0); Address : IN std_logic_vector(ADDRESS_WIDTH-1 downto 0); WriteEn : IN std_logic; Enable : IN std_logic; DataOut : OUT std_logic_vector(DATA_WIDTH-1 downto 0) ); END COMPONENT; --Inputs signal Clock : std_logic := '0'; signal Reset : std_logic := '1'; signal DataIn : std_logic_vector(7 downto 0) := (others => '0'); signal Address : std_logic_vector(4 downto 0) := (others => '0'); signal WriteEn : std_logic := '0'; signal Enable : std_logic := '0'; --Outputs signal DataOut : std_logic_vector(7 downto 0); -- Clock period definitions constant CLK_period : time := 10 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut : RAM Generic map ( DATA_WIDTH => datain'length, ADDRESS_WIDTH => address'length ) PORT MAP ( Clock => Clock, Reset => Reset, DataIn => DataIn, Address => Address, WriteEn => WriteEn, Enable => Enable, DataOut => DataOut ); -- Clock process definitions CLK_process : process begin Clock <= '0'; wait for CLK_period/2; Clock <= '1'; wait for CLK_period/2; end process; -- Stimulate Write process stim_write_read : process begin -- write wait for CLK_period * 1; Address <= "00000"; Reset <= '0'; for i in 0 to 2 loop WriteEn <= '1'; Enable <= '1'; wait for CLK_period * 1; Address <= Address + 4; DataIn <= DataIn + 3; end loop; -- read Address <= "00000"; for k in 0 to 2 loop WriteEn <= '0'; Enable <= '1'; wait for CLK_period * 1; Address <= Address + 4; end loop; Enable <= '1'; wait; end process; end;
  20. hamster

    how to define constraint

    Yep - like Alex says - you just need to add the index to the name of the signal: set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { gpio2_io_o[0] }]; set_property -dict { PACKAGE_PIN some_other_pin IOSTANDARD LVCMOS33 } [get_ports { gpio2_io_o[1] }]; ... set_property -dict { PACKAGE_PIN some_other_pin IOSTANDARD LVCMOS33 } [get_ports { gpio2_io_o[7] }];
  21. Hi. I've replaced my Cubieboard with a Raspberry Pi 3, and it runs the ARM version of Waveforms really well. With an Electronics Explorer everything works sweet. With the AD2, it complains about supply and/or AUX voltage, even with a 5V 3A power pack attached (The power supply panel indicates that the AUX supply is present so I know it is working well). The USB voltage usually shows as 4.92V at a few 10s of mAs I've tried with 2.5A USB PSU => Pi3 => Powered Hub => AD2, as well as 2.5A USB PSU => Pi3 => AD2. I also get a "unsufficent power". I've tried a few different USB cables too. The USB 2.0 spec, according to Wikipedia is 5V +/- 0.25V, so anything above 4.75V should be possible. Is there any hints? If I wanted to make a USB dummy load and test the voltage drop, what specs should I be checking for?
  22. If you suggest one, and we'll make it better together? there is actually quiet a bit that could be tested. Writing & reading the same address at the same time, or reading the address the cycle after it is written,, with/without write enable set, does read enable work correctly... Do you have any sort of a test plan drawn up, detailing what you want to test?
  23. Duty cycle isn't that important (it has to be between 45% and 55%) , but it has to be perfect integer ratio between MCLK and the other signals. You might be able to run the PMOD with internal clocking mode - SCLK isn't actively driven, just tie it high. That might allow you to use a perfect integer MCLK. Have a look at 4.2.2 in the datasheet. If you don't make any headway, I could try configuring my design for an internal serial clock.
  24. I'll get you a trace tonight if I can. The master clock isn't too important. It can be anything from 0.5 MHz to 50 MHz, but of course most of these will not give "industry standard" sample rates. I've been using it on a few different boards, including the Basys3. Also, be careful to check your pin assignments. For a while the schematic and PMOD reference manual didn't agree on pin ordering (the schematic was correct). All of the signals must be an integer ratio of mclk - i.e. you can't have 256.001 mclk ticks per frame. So if you see the phase of the LR or SDIN changing with respect to the MCLK then it won't work.
  25. Hi TJ Your code is 99% of the way there. Here's the last 1% that I can see. - I am not sure that you need "we" and "re" on your sensitivity list. I would reformat the code with nested 'if's. e.g.: mem_read : process (clk_out) begin if clk_out'event and clk_out = '1' then if re = '1' then data_out <= mem( conv_integer( addr_out)) ; end if ; end if ; end process read; - There is a more subtle problem. As the read and write is split over two different processes, there is a bit of flexibility in which occurs first and which occurs second. I don't know the full semantics of this (do both processes get run, then the updates occur? or do they individually run and update, with flexibility as to who gets to run first). Seems to be a perfect place for some undefined behavior to occur, causing a simulation / synthesis miss-match. I would recommend that you fix this by putting everything in one process. - You really want to initialize the contents of your memory array, otherwise simulation will not match what occurs in the FPGA. signal mem : mem_type := (others => (others => '0'));