Commit 8a83cba7 authored by David Cussans's avatar David Cussans

Comitting changes for working demo version

* marocInterface_rtl.vhd - detects the falling edge of status from marocADC
* circuit to detect falling edge of status hdl/fallingEdgeDetect_rtl.vhd



git-svn-id: https://svn2.phy.bris.ac.uk/svn/uob-hep-pc049a/trunk@33 e1591323-3689-4d5a-aa31-d1a7cbdc5706
parent bd6c7e83
......@@ -105,7 +105,7 @@ ARCHITECTURE rtl OF IPBusInterfaceGTP IS
signal s_ipbw_internal: ipb_wbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_ipbr_internal: ipb_rbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_sysclk : std_logic;
signal pkt_rx, pkt_tx, pkt_rx_led, pkt_tx_led, sys_rst: std_logic;
signal pkt_rx, pkt_tx, pkt_rx_led, pkt_tx_led, sys_rst: std_logic := '0';
BEGIN
......@@ -114,18 +114,6 @@ BEGIN
sfp_scl_o <= '1';
sfp_sda_o <= '1';
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_s6_basex port map(
sysclk_i => sysclk_i,
clki_125 => clk125,
clko_ipb => s_ipb_clk,
sysclko => s_sysclk,
locked => locked,
nuke => sys_rst,
rsto_125 => rst_125,
rsto_ipb => rst_ipb,
onehz => onehz_o
);
-- Connect IPBus clock and reset to output ports.
ipb_clk_o <= s_ipb_clk;
......@@ -141,6 +129,19 @@ BEGIN
--! By default generate a Gigabit serial MAC
generate_physicalmac: if ( BUILD_SIMULATED_ETHERNET /= 1 ) generate
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_s6_basex port map(
sysclk_i => sysclk_i,
clki_125 => clk125,
clko_ipb => s_ipb_clk,
sysclko => s_sysclk,
locked => locked,
nuke => sys_rst,
rsto_125 => rst_125,
rsto_ipb => rst_ipb,
onehz => onehz_o
);
eth: entity work.eth_s6_1000basex port map(
gtp_clkp => gtp_clkp,
gtp_clkn => gtp_clkn,
......@@ -169,10 +170,23 @@ BEGIN
--! Set generic BUILD_SIMULATED_ETHERNET to 1 to generate a simulated MAC
generate_simulatedmac: if ( BUILD_SIMULATED_ETHERNET = 1 ) generate
sim_clocks: entity work.clock_sim
port map (
clko125 => clk125,
clko25 => s_ipb_clk,
clko40 => open,
nuke => '0',
rsto => rst_125
);
rst_ipb <= rst_125;
locked <= '1';
-- clk125 <= sysclk_i; -- *must* run this simulation with 125MHz sysclk...
simulated_eth: entity work.eth_mac_sim
port map(
clk => clk125,
rst => rst,
rst => rst_125,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
......
......@@ -6,7 +6,7 @@
-- Dave Newbold, April 2011
--
-- DGC , 26/March/2015 Modified original (which generated a 25MHz ipbus clock from 200MHz xtal reference)
-- $Id$
-- change for 15.625 MHz clock to help debug timing. 9/apr/15
library ieee;
use ieee.std_logic_1164.all;
......@@ -44,12 +44,14 @@ begin
o => clk_ipb_b
);
-- 125MHz input ( 8ns period ), 31.25MHz output ( 32ns )
-- 125MHz input ( 8ns period ), 31.25MHz output ( 32ns )
-- 125MHz input ( 8ns period ), 15.625MHz output ( 64ns ) --- put in to make timing clearer
dcm0: DCM_CLKGEN
generic map(
CLKIN_PERIOD => 8.0,
CLKFX_MULTIPLY => 2,
CLKFX_DIVIDE => 8
CLKFX_DIVIDE => 8 -- 31.25MHz
-- CLKFX_DIVIDE => 16 -- 15.625MHz
)
port map(
clkin => sysclk_i,
......@@ -82,11 +84,12 @@ begin
begin
if rising_edge(clk_ipb_b) then
rst_ipb <= rst;
rsto_ipb <= rst_ipb; -- Delay by extrac clock cycle to give extra time for routing.
nuke_i <= nuke;
end if;
end process;
rsto_ipb <= rst_ipb;
process(clki_125)
begin
......
-- clocks_s6_basex
--
-- Generates a 25MHz ipbus clock from 200MHz xtal reference
-- Generates a 31.25MHz ipbus clock from 125MHz xtal reference
-- Includes reset logic for ipbus
--
-- Dave Newbold, April 2011
--
-- DGC , 26/March/2015 Modified original (which generated a 25MHz ipbus clock from 200MHz xtal reference)
-- $Id$
library ieee;
......@@ -14,8 +15,7 @@ library unisim;
use unisim.VComponents.all;
entity clocks_s6_basex is port(
sysclk_p: in std_logic;
sysclk_n: in std_logic;
sysclk_i: in std_logic;
clki_125: in std_logic;
clko_ipb: out std_logic;
sysclko: out std_logic;
......@@ -36,13 +36,7 @@ architecture rtl of clocks_s6_basex is
begin
ibufgds0: IBUFGDS port map(
i => sysclk_p,
ib => sysclk_n,
o => sysclk
);
sysclko <= sysclk;
sysclko <= sysclk_i;
clko_ipb <= clk_ipb_b;
bufg_ipb: BUFG port map(
......@@ -50,28 +44,29 @@ begin
o => clk_ipb_b
);
-- 125MHz input ( 8ns period ), 31.25MHz output ( 32ns )
dcm0: DCM_CLKGEN
generic map(
CLKIN_PERIOD => 5.0,
CLKIN_PERIOD => 8.0,
CLKFX_MULTIPLY => 2,
CLKFX_DIVIDE => 16
CLKFX_DIVIDE => 8
)
port map(
clkin => sysclk,
clkin => sysclk_i,
clkfx => clk_ipb_i,
locked => dcm_locked,
rst => '0'
);
clkdiv: entity work.clock_div port map(
clk => sysclk,
clk => sysclk_i,
d17 => d17,
d28 => onehz
);
process(sysclk)
process(sysclk_i)
begin
if rising_edge(sysclk) then
if rising_edge(sysclk_i) then
d17_d <= d17;
if d17='1' and d17_d='0' then
rst <= nuke_d2 or not dcm_locked;
......
--! @file fallingEdgeDetect_rtl
--! @brief Detects the falling edge of an incoming signal and produces a single cycle pulse
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity fallingEdgeDetect is
port (
clk_i : in std_logic; -- ! falling edge active clock
level_i : in std_logic; -- ! Level
pulse_o : out std_logic); -- ! Pulses high for one clock cycle when level_i goes from high to low
end entity fallingEdgeDetect;
architecture rtl of fallingEdgeDetect is
signal level_d1 , level_d2 : std_logic := '0'; -- delayed version of input
begin -- architecture rtl
p_levelDetect: process (clk_i) is
begin -- process p_levelDetect
if rising_edge(clk_i) then -- rising clock edge
level_d1 <= level_i;
level_d2 <= level_d1;
if (( level_d2 = '1' ) and ( level_d1 = '0')) then
pulse_o <= '1';
else
pulse_o <= '0';
end if;
end if;
end process p_levelDetect;
end architecture rtl;
......@@ -20,15 +20,17 @@ use work.ipbus.all;
--
--! @brief Interfaces between IPBus and Maroc ADC\n
--! Addresses ( with respect to base address)\n
--! 0x00 - 0x2FF : ADC data ( ro )\n
--! 0x200 : control/status.
--! Data bus:\n
--! 0x000 - 0xFFF : ADC data ( ro )\n
--! Control bus:\n
--! 0x0 : control/status.
--! Writing '1' to bit-0 starts conversion.\n
--! Reading bit-0 returns high if conversion is in progress\n
--! Writing '1' to bit-1 resets write pointer\n
--! 0x201 : returns the number of bits shifted out by MAROC ADC\n
--! 0x1 : returns the number of bits shifted out by MAROC ADC\n
--! during last conversion ( ro )\n
--! 0x202 : DPRAM write-pointer (next address to be written to ( ro )\n
--
--! 0x2 : DPRAM write-pointer (next address to be written to ( ro )\n
--! 0x3 : Returns an identification word set by generic. Useful if more than 1 maroc on board.
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 4\Jan\2012
......@@ -42,12 +44,12 @@ use work.ipbus.all;
--!
--! There are two ways to trigger an ADC conversion:
--! a) A pulse on adcConversionStart_i
--! b) Writing to bit-0 of address 0x20
--! b) Writing to bit-0 of address 0x0 on the control IPBus
--!
--! As serial data arrives from ADC the earliest data ends up in highest bits of
--! the lowest words in the DPRAM.
--!
--! Data are written to a DPRAM. Address 0x402 stores the location that the next
--! Data are written to a DPRAM. Address 0x2 in the control IPBus stores the location that the next
--! word that will be written (the "write pointer").
--! The ADC data are preceeded by a trigger number word
--! and a timestamp word. Hence with the Maroc set to 12-bit samples the total
......@@ -74,7 +76,9 @@ use work.ipbus.all;
--! 7/March/2012 DGC Got rid of FIFO and make DPRAM big enough to act as a
--! circular buffer\n
--! 17/March/2012 DGC Add internal reset, to reset state of ADC\n
--! 9/May/2013 DGC Reduced buffer size to 512 words
--! 9/May/2013 DGC Reduced buffer size to 512 words\n
--! 1/Apr/2015 DGC Increased buffer size to 4096 words. Documented split in\
--! data and control address spaces.
-------------------------------------------------------------------------------
--! @todo
---------------------------------------------------------------------------------
......@@ -82,7 +86,7 @@ use work.ipbus.all;
entity ipbusMarocADC is
generic(
g_ADDRWIDTH : positive := 9; --! Number of words in the data buffer
g_ADDRWIDTH : positive := 12; --! Number of words in the data buffer
--! is 2^g_ADDRWIDTH
g_BUSWIDTH : positive := 32; --! Width of data bus
g_IDENT : std_logic_vector(31 downto 0) := X"DEADBEEF"
......@@ -188,7 +192,6 @@ begin
if rising_edge(clk_i) then
if control_ipbus_i.ipb_strobe = '1' and control_ipbus_i.ipb_write = '1' and
control_ipbus_i.ipb_addr(g_ADDRWIDTH) = '1' and
control_ipbus_i.ipb_addr(1 downto 0) = "00"
then
s_internal_start_p <= control_ipbus_i.ipb_wdata(0);
......
......@@ -96,7 +96,7 @@ architecture rtl of ipbusMarocTriggerGenerator is
signal s_ack: std_logic;
signal s_counter_reset , s_counter_reset_ipb : std_logic;
signal s_counter_reset , s_counter_reset_ipb , s_counter_reset_ipb_d1: std_logic;
signal s_conversion_counter : std_logic_vector(g_BUSWIDTH-1 downto 0) := (others => '0');
signal s_timeStamp : std_logic_vector(g_BUSWIDTH-1 downto 0) := (others => '0');
......@@ -196,12 +196,13 @@ begin
s_counter_reset_ipb <= '0';
end if;
end if;
s_counter_reset_ipb_d1 <= s_counter_reset_ipb; -- Extra register to ease routing.
end process p_resetCounter;
ipbus_o.ipb_ack <= s_ack;
ipbus_o.ipb_err <= '0';
s_counter_reset <= s_counter_reset_ipb or logic_reset_i or reset_i;
s_counter_reset <= s_counter_reset_ipb_d1 or logic_reset_i or reset_i;
-- Instantiate the TriggerGenerator
cmp_TriggerGeneratorInterface: entity work.marocTriggerGenerator
......
......@@ -28,16 +28,20 @@ package body ipbus_addr_decode is
variable sel : integer;
begin
if std_match(addr, "-------------------0--001-------") then
if std_match(addr, "-----------------00---001-------") then
sel := 0; -- scshiftreg / base 00000080 / mask 0000007f
elsif std_match(addr, "-------------------0--010-------") then
elsif std_match(addr, "-----------------00---010-------") then
sel := 1; -- rshiftreg / base 00000100 / mask 0000007f
elsif std_match(addr, "-------------------0--110-------") then
elsif std_match(addr, "-----------------00---110-------") then
sel := 2; -- triggerctrl / base 00000300 / mask 000007f
elsif std_match(addr, "-------------------1--000-------") then
sel := 3; -- adc / base 00001000 / mask 00000fff
elsif std_match(addr, "-------------------0--000-------") then
sel := 5; -- firmwareid / base 00000000 / mask 00000000
elsif std_match(addr, "-----------------01-------------") then
sel := 3; -- adcData / base 00002000 / mask 00000fff
elsif std_match(addr, "-----------------10-------------") then
sel := 4; -- adcCtrl / base 00004000 / mask 00000fff
elsif std_match(addr, "-----------------11-------------") then
sel := 5; -- expansionIO/ base 00006000 / mask 00000fff
elsif std_match(addr, "-----------------00---000-------") then
sel := 6; -- firmwareid / base 00000000 / mask 00000000
else
sel := 99;
end if;
......
......@@ -20,7 +20,7 @@ architecture rtl of ipbus_ver is
begin
ipbus_out.ipb_rdata <= X"a61f" & X"1008"; -- Lower 16b are ipbus firmware build ID (temporary arrangement).
ipbus_out.ipb_rdata <= X"a621" & X"1008"; -- Lower 16b are ipbus firmware build ID (temporary arrangement).
ipbus_out.ipb_ack <= ipbus_in.ipb_strobe;
ipbus_out.ipb_err <= '0';
......
......@@ -56,7 +56,6 @@ end marocInterface;
architecture rtl of marocInterface is
signal register_data: std_logic_vector(c_BUSWIDTH-1 downto 0);
signal s_adcConversionStatus : std_logic;
signal s_adcConversionEnd : std_logic;
signal s_adcConversionStart : std_logic;
......@@ -71,17 +70,6 @@ architecture rtl of marocInterface is
begin -- rtl
-- --! Slave 1: 32b register ( output from FPGA to MAROC)
-- slave0: entity work.ipbus_reg
-- generic map(addr_width => 0)
-- port map(
-- clk => ipb_clk_i,
-- reset => rst_i,
-- ipbus_in => ipb_in(0),
-- ipbus_out => ipb_out(0),
-- q => register_data
-- );
-- Slave 0: slow control shift register controller
slave0: entity work.ipbusMarocShiftReg
generic map(
......@@ -128,51 +116,14 @@ begin -- rtl
rst_sr_n_o => rst_r_n_o
);
-- Slave 2: Simple ADC controller
slave2: entity work.ipbusMarocADC
generic map(
g_ADDRWIDTH => 10 )
port map(
-- signals to IPBus
clk_i => ipb_clk_i,
reset_i => rst_i,
control_ipbus_i => ipb_in(2),
control_ipbus_o => ipb_out(2),
data_ipbus_i => ipb_in(3),
data_ipbus_o => ipb_out(3),
-- global reset signal
logic_reset_i => '0',
-- Signals to trigger controller
adcStatus_o => s_adcConversionStatus,
adcConversionStart_i => s_adcConversionStart,
triggerNumber_i => s_triggerNumber ,
timeStamp_i => s_timeStamp ,
-- Signals to MAROC
START_ADC_N_O => START_ADC_N_O,
RST_ADC_N_O => RST_ADC_N_O,
ADC_DAV_I => ADC_DAV_I,
OUT_ADC_I => OUT_ADC_I
);
-- FIXME - this should be edge sensitive.... ir trigger generator changed to
-- be level sensitive.
s_adcConversionEnd <= s_adcConversionStatus;
-- FIXME - clk fast
-- Slave 3: Trigger generator
slave3: entity work.ipbusMarocTriggerGenerator
-- Slave 2: Trigger generator
slave2: entity work.ipbusMarocTriggerGenerator
port map (
-- signals to IPBus
clk_i => ipb_clk_i,
reset_i => rst_i,
ipbus_i => ipb_in(4),
ipbus_o => ipb_out(4),
ipbus_i => ipb_in(2),
ipbus_o => ipb_out(2),
-- Signals to MAROC and ADC controller
adcConversionEnd_i => s_adcConversionEnd,
......@@ -201,6 +152,48 @@ begin -- rtl
trigger_o <= s_externalTrigger_o;
-- gpio_o(5) <= s_externalTrigger_o;
-- Slave 3&4: Simple ADC controller
slave3_4: entity work.ipbusMarocADC
generic map(
g_ADDRWIDTH => 12 )
port map(
-- signals to IPBus
clk_i => ipb_clk_i,
reset_i => rst_i,
control_ipbus_i => ipb_in(4),
control_ipbus_o => ipb_out(4),
data_ipbus_i => ipb_in(3),
data_ipbus_o => ipb_out(3),
-- global reset signal
logic_reset_i => '0',
-- Signals to trigger controller
adcStatus_o => s_adcConversionStatus,
adcConversionStart_i => s_adcConversionStart,
triggerNumber_i => s_triggerNumber ,
timeStamp_i => s_timeStamp ,
-- Signals to MAROC
START_ADC_N_O => START_ADC_N_O,
RST_ADC_N_O => RST_ADC_N_O,
ADC_DAV_I => ADC_DAV_I,
OUT_ADC_I => OUT_ADC_I
);
-- Look for adc conversion status going from high ( ADC busy ) to low ( ADC
-- idle ) and produce an adcConversionEnd signal. This extra step makes more
-- sense with multiple ADCs......
edgeDetect: entity work.fallingEdgeDetect
port map (
clk_i => ipb_clk_i,
level_i => s_adcConversionStatus,
pulse_o => s_adcConversionEnd
);
-- FIXME - clk fast
-- FIXME - connect combination of MAROC signals to an output
s_tree_or(0) <= '0';
......
......@@ -37,7 +37,8 @@ USE UNISIM.vcomponents.all;
--! Delays trigger by hold1Delay_i cycles of clk_fast_i and then asserts hold1.
--! Delays hold1 by hold2Delay_i cycles of clk_fast_i then asserts hold2
--! After asserting hold2 outputs a pulse on adcStartConversion_o , last for single cycle of clk_sys_i
--! When the ADC controller signals end of conversion by pulsing adcConversionEnd_i then
--! When the ADC controller signals end of conversion by pulsing adcConversionEnd_i
--high then
--! hold1,hold2 are deasserted.
--!
--! <b>Dependencies:</b>\n
......@@ -66,7 +67,7 @@ ENTITY marocTriggerGenerator IS
generic (
g_BUSWIDTH : integer := 32);
PORT(
adcConversionEnd_i : IN std_logic; --! end of conversion signal from ADC controller. Sync with rising edge of clk_sys_i
adcConversionEnd_i : IN std_logic; --! end of conversion signal from ADC controller. Goes high for one clock, Sync with rising edge of clk_sys_i
clk_fast_i : IN std_logic; --! Fast clock used to register and delay trigger signals
clk_sys_i : IN std_logic; --! system clock used for adcConversionEnd_o , adcConversionStart_i
reset_i : in std_logic; --! Active high. Resets s_preDelayHold and counter value
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment