library IEEE; use IEEE.std_LOGIC_1164.ALL; -- the next two packages are necessary in order to use arithmetic expressions with std_logic_vectors use ieee.std_logic_arith.all; -- interpret the std_logic_vectors as unsigned use ieee.std_logic_unsigned.all; entity top_core is Generic(ClkMHz : integer := 100); Port ( CLK : in std_logic; Reset : in std_logic; -- put here the signals to the SUxxx modules -- Slot 0 is empty -- SU704 on slot 1 SU1_INTTL : in std_logic_vector( 5 downto 1); SU1_OUTP : out std_logic_vector( 5 downto 1); SU1_INECL : in std_logic_vector( 5 downto 1); SU1_OE_n : out std_logic_vector( 5 downto 1); SU1_LED_n : out std_logic_vector( 5 downto 1); SU1_TERM : out std_logic_vector( 5 downto 1); -- Slot 2 is empty -- Slot 3 is empty -- Slot 4 is empty -- Slot 5 is empty -- Slot 6 is empty -- Slot 7 is empty -- end of the SUxxx section Tick1ms : in std_logic; Tick20ms : in std_logic; -- DMA config & handshaking DMA_ena : in std_logic; -- DMA enabled DMA_ack : in std_logic; -- DMA acknoledge DMA_req : out std_logic; -- request, activate only when DMA_ena=1, deactivate after ack DMA_Nwords : out std_logic_vector(15 downto 0); -- Number of words DMA_Addr : out std_logic_vector(31 downto 0); -- start address DMA_dsize : out std_logic_vector( 1 downto 0); -- 0..3 for 1..4 bytes DMA_Ainc : out std_logic; -- auto increment of the address -- IF CAddr : in std_logic_vector(31 downto 0); CWR : in std_logic; CRD : in std_logic; CDIn : in std_logic_vector(31 downto 0); CDOut : out std_logic_vector(31 downto 0); CRdy : out std_logic); end top_core; architecture unsere of top_core is constant max_timer : Integer := ClkMHz*1000000-1; signal timer : Integer range 0 to max_timer; signal copy_rst : std_logic; signal inp_edge : std_logic_vector(1 downto 0); signal cnt_ena : std_logic; signal counter, counter_cp : std_logic_vector(31 downto 0); signal generator : std_logic_vector(6 downto 0); begin -- output 1 is the output of the generator, all others are unused SU1_OUTP <= (5 => generator(generator'high), others => '0'); -- output enabled only in channel 5 SU1_OE_n <= (5 => '0', others => '1'); -- termination only in channel 1 (the input) SU1_TERM <= (1 => '1', others => '0'); -- the ready for the Cbus, if not wired will be 0 and the USB controller waits for ever! CRDy <= '1'; -- detect a positive edge at the input, sample twice in a shift register process(clk) begin if rising_edge(clk) then -- shift register with two bits inp_edge <= inp_edge(0) & SU1_INTTL(1); -- new is 1 and the old is 0 cnt_ena <= inp_edge(0) and not inp_edge(1); -- binary counter, used to generate some output generator <= generator + 1; end if; end process; -- counter for the detected edges process(clk) begin if rising_edge(clk) then -- if copy & reset - latch the counter to the register and clear the counter -- for the next counting period. if copy_rst='1' then -- take into account a possible edge detected right now counter <= (0 => cnt_ena, others => '0'); counter_cp <= counter; elsif cnt_ena='1' then -- count up counter <= counter + 1; end if; end if; end process; -- read mux, either the latched counts or the running counter CDout <= counter_cp when CAddr(0)='0' else counter; -- output register to control the LEDs process(clk) begin if rising_edge(clk) then if Reset='1' then -- all LEDs are on after reset SU1_LED_n <= (others => '0'); elsif CWR='1' then -- invert when writing, so writing 1 will turn the LED on SU1_LED_n <= not CDIn(SU1_LED_n'length-1 downto 0); end if; end if; end process; -- timer, produce once in a second a pulse one period long process(clk) begin if rising_edge(clk) then if timer > 0 then -- count down timer <= timer - 1; -- deactivate copy & reset copy_rst <= '0'; else -- load with the max value timer <= max_timer; -- activate copy & reset copy_rst <= '1'; end if; end if; end process; end;