- Muchas notas - Fran Acién

20230116 - Advices for VHDL

Here are some notes of things that I learnt by failing:

  • integer and natural is not recomended cuz you cannot set the number of bits.
  • The variables in this style:
    • i_ Input signal
    • o_ Output signal
    • r_ Register signal (has registered logic)
    • w_ Wire signal (has no registered logic)
    • c_ Constant
    • g_ Generic (VHDL only)
    • t_ User-Defined Type
    • p_ Process
  • The architectures and entities should be called in minus. Otherwise they generate errors in simulation.
  • Dont give a initial value to registers when you create them, it is ignored in the synthesis process. It should be initialized in the reset.

For some reason when you call an entity and you want to negate an input, you should do it as:

UUT_adc : entity work.adc_interface
		port map(
			i_clk  						=> i_clk,
			i_rst_l 				    => "not"(i_rst),
			                  
			o_adc_clk_12MHz   => o_adc_clk_12MHz,
			o_adc_nCs 			  => o_adc_nCs,
			i_adc_sdo 			  => i_adc_sdo,
			                  
			o_rx_adc 				  => w_rx_adc,
			o_rx_dv 					=> w_rx_dv
		);

Project structure

7a04e2181cac4e9976122a282658e502.png

I prefer this way, that I saw on this IP:

  • docs: A PDF with the documentation of the project. Explaining the testbench etc.
  • project: Folder for the radiant project.
  • simulation: Folder for saving the wave files, and the input/output of the tests.
  • source: The source code, a subfolder called vhdl
  • testbench: A subfolder called vhdl with the testbenches

Reset and initializing signals

  • Source

  • DONT INITIALIZE A SIGNAL WITH A DEFAULT VALUE, The synthesis will ignore it. The simulation and the implementation will differ.

  • Use synchronous reset, guidelines of xilinx

  • Active-high resets enable better device utilization and improve performance.

  • it is recommended that you use the dedicated hardwired GSR. Check if the GSR is in auto.

library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;

entity main is
  port (
    i_clock : in std_logic;
    o_led : out std_logic;
    i_rst : in std_logic
  ) ;
end entity main;

architecture arch of main is

    constant CLOCK_FREQUENCY : integer := 12000000; -- input clock frequency (12 MHz)
    
	signal counter : unsigned(31 downto 0); -- 32-bit counter to measure 1 second
    signal r_led : std_logic;
begin

    PROC_LIGHT : process( i_clock )
    begin
		if rising_edge(i_clock) then -- detect rising edge of input clock
			if (i_rst='1') then
				counter <= (others => '0');
				r_led <= '0';
			else
                counter <= counter + 1; -- increment counter on each clock cycle
                if counter = to_unsigned(CLOCK_FREQUENCY, counter'length) then -- check if counter reaches 1 second
                    r_led <= not r_led; -- toggle the LED on and off
                    counter <= (others => '0'); -- reset the counter to start again
                end if;
            end if;
		end if;
    end process ; -- PROC_LIGHT
  
  o_led <= r_led;

end arch ; -- arch