architecture input_statistics_arch of input_statistics is
signal inp_reg : std_logic_vector(INPUTS-1 downto 0);
+signal inp_reg_last : std_logic_vector(INPUTS-1 downto 0);
signal trigger_fifo : std_logic;
signal reset_cnt : std_logic;
+signal timer_rst : std_logic;
signal enable : std_logic_vector(31 downto 0);
signal invert : std_logic_vector(31 downto 0);
signal rate : unsigned(31 downto 0);
-signal fifo_read : std_logic_vector(31 downto 0);
+signal fifo_read : std_logic_vector(31 downto 0);
+signal fifo_wait,fifo_wait2,fifo_wait3 : std_logic;
+signal fifo_empty : std_logic_vector(31 downto 0);
+signal fifo_write : std_logic;
signal fifo_select : integer range 0 to 31;
+type cnt_t is array(0 to 31) of unsigned(23 downto 0);
+signal cnt : cnt_t;
+
+type dout_t is array(0 to 31) of std_logic_vector(17 downto 0);
+signal fifo_dout : dout_t;
+
+type fifo_count_t is array(0 to 31) of std_logic_vector(10 downto 0);
+signal fifo_count : fifo_count_t;
+
+signal timer : unsigned(31 downto 0);
+signal word_cnt : unsigned(11 downto 0);
+
+type state_t is (IDLE,RUN,CHECK);
+signal state : state_t;
+
+signal status_reg : std_logic_vector(31 downto 0);
+
begin
THE_CONTROL : process
- variable tmp : integer range 0 to 15;
+ variable tmp : integer range 0 to 31;
begin
wait until rising_edge(CLK);
ACK_OUT <= '0';
NACK_OUT <= '0';
trigger_fifo <= '0';
+ reset_cnt <= '0';
+ timer_rst <= '0';
fifo_read <= (others => '0');
- fifo_select <= 0;
+ fifo_wait <= '0';
+ tmp := to_integer(unsigned(ADDR_IN(4 downto 0)));
if WRITE_IN = '1' then
- if ADDR_IN(6 downto 4) = "000" then
+ if ADDR_IN(6 downto 4) = "000" and tmp < INPUTS then
ACK_OUT <= '1';
case ADDR_IN(3 downto 0) is
when x"0" => enable <= DATA_IN;
when x"1" => invert <= DATA_IN;
when x"2" => rate <= unsigned(DATA_IN);
+ timer_rst <= '1';
when x"f" => trigger_fifo <= DATA_IN(0);
reset_cnt <= DATA_IN(1);
when others => NACK_OUT <= '1'; ACK_OUT <= '0';
NACK_OUT <= '1';
end if;
elsif READ_IN = '1' then
- if ADDR_IN(6 downto 4) = "000" then
+ if ADDR_IN(6 downto 4) = "000" and tmp < INPUTS then
ACK_OUT <= '1';
case ADDR_IN(3 downto 0) is
when x"0" => DATA_OUT <= enable;
when x"1" => DATA_OUT <= invert;
when x"2" => DATA_OUT <= std_logic_vector(rate);
+ when x"3" => DATA_OUT <= timer;
+ when x"4" => DATA_OUT <= status_reg;
when x"e" => DATA_OUT(INPUTS-1 downto 0) <= inp_reg; DATA_OUT(31 downto INPUTS) <= (others => '0');
when others => DATA_OUT <= (others => '0');
end case;
- elsif ADDR_IN(6 downto 4) = "001" or ADDR_IN(6 downto 5) = "010" then
+ elsif ADDR_IN(6 downto 5) = "01" and tmp < INPUTS then
fifo_read(to_integer(unsigned(ADDR_IN(4 downto 0)))) <= '1';
fifo_select <= to_integer(unsigned(ADDR_IN(4 downto 0)));
+ fifo_wait <= '1';
+ elsif ADDR_IN(6 downto 5) = "10" and tmp < INPUTS then
+ DATA_OUT(23 downto 0) <= cnt(to_integer(unsigned(ADDR_IN(4 downto 0))));
+ ACK_OUT <= '1';
+ else
+ NACK_OUT <= '1';
end if;
+ elsif fifo_wait3 = '1' then
+ DATA_OUT(17 downto 0) <= fifo_dout(fifo_select);
+ DATA_OUT(31) <= fifo_empty(fifo_select);
+ DATA_OUT(30 downto 18)<= (others => '0');
+ ACK_OUT <= '1';
end if;
end process;
+fifo_wait2 <= fifo_wait when rising_edge(CLK);
+fifo_wait3 <= fifo_wait2 when rising_edge(CLK);
inp_reg <= INPUT when rising_edge(CLK);
+inp_reg_last <= inp_reg when rising_edge(CLK);
+
+gen_counters : for i in 0 to INPUTS-1 generate
+ process begin
+ wait until rising_edge(CLK);
+ if reset_cnt = '1' then
+ cnt(i) <= (others => '0');
+ elsif inp_reg(i) = not invert(i) and inp_reg_last(i) = invert(i) and enable(i) = '1' then
+ cnt(i) <= cnt(i) + 1;
+ end if;
+ end process;
+end generate;
+
+
+proc_ctrl : process begin
+ wait until rising_edge(CLK);
+ fifo_write <= '0';
+ case state is
+ when IDLE =>
+ if trigger_fifo = '1' then
+ state <= RUN;
+ word_cnt <= (others => '0');
+ end if;
+ when RUN =>
+ timer <= timer + 1;
+ if timer = rate then
+ fifo_write <= '1';
+ word_cnt <= word_cnt + 1;
+ timer <= (others => '0');
+ state <= CHECK;
+ end if;
+
+ when CHECK =>
+ if word_cnt = x"400" then
+ state <= IDLE;
+ else
+ state <= RUN;
+ end if;
+ end case;
+ if timer_rst = '1' then
+ timer <= (others => '0');
+ end if;
+end process;
+
+gen_fifos : for i in 0 to INPUTS-1 generate
+ THE_FIFO : entity work.fifo_18x1k_oreg
+ port map (
+ Data => std_logic_vector(cnt(i)(17 downto 0)),
+ Clock => CLK,
+ WrEn => fifo_write,
+ RdEn => fifo_read(i),
+ Reset => trigger_fifo,
+ AmFullThresh => "1000000000",
+ Q => fifo_dout(i),
+ WCNT => fifo_count(i),
+ Empty => fifo_empty(i),
+ Full => open,
+ AlmostFull => open
+ );
+end generate;
+
+status_reg(10 downto 0) <= fifo_count(0);
+status_reg(11) <= fifo_write;
+status_reg(15 downto 12)<= (others => '0');
+status_reg(27 downto 16)<= word_cnt;
+status_reg(31 downto 28)<= (others => '0');
+
end architecture;
\ No newline at end of file
THE_CONTROL : process
- variable tmp : integer range 0 to 15;
+ variable tmp : integer range 0 to 16;
begin
wait until rising_edge(CLK);
ACK_OUT <= '0';
NACK_OUT <= '0';
- tmp := to_integer(unsigned(ADDR_IN(5 downto 2)));
+ tmp := to_integer(unsigned(ADDR_IN(4 downto 1)));
if WRITE_IN = '1' then
ACK_OUT <= '1';
- case ADDR_IN(1 downto 0) is
- when "00" => enable(tmp) <= DATA_IN;
- when "01" => invert(tmp) <= DATA_IN;
- when others => NACK_OUT <= '1'; ACK_OUT <= '0';
- end case;
+ if ADDR_IN(5) = '0' and tmp < OUTPUTS then
+ case ADDR_IN(0) is
+ when '0' => enable(tmp) <= DATA_IN;
+ when '1' => invert(tmp) <= DATA_IN;
+ end case;
+ else
+ NACK_OUT <= '1';
+ ACK_OUT <= '0';
+ end if;
elsif READ_IN = '1' then
ACK_OUT <= '1';
- case ADDR_IN(1 downto 0) is
- when "00" => DATA_OUT <= enable(tmp);
- when "01" => DATA_OUT <= invert(tmp);
- when "10" => DATA_OUT(INPUTS-1 downto 0) <= inp_reg; DATA_OUT(31 downto INPUTS) <= (others => '0');
- when "11" => DATA_OUT(OUTPUTS-1 downto 0) <= out_reg; DATA_OUT(31 downto OUTPUTS) <= (others => '0');
- when others => DATA_OUT <= (others => '0');
- end case;
+ if ADDR_IN(5) = '0' and tmp < OUTPUTS then
+ case ADDR_IN(0) is
+ when '0' => DATA_OUT <= enable(tmp);
+ when '1' => DATA_OUT <= invert(tmp);
+ end case;
+ elsif ADDR_IN(5) = '0' and tmp >= OUTPUTS then
+ NACK_OUT <= '1';
+ ACK_OUT <= '0';
+ else
+ case ADDR_IN(1 downto 0) is
+ when "00" => DATA_OUT(INPUTS-1 downto 0) <= inp_reg; DATA_OUT(31 downto INPUTS) <= (others => '0');
+ when "01" => DATA_OUT(OUTPUTS-1 downto 0) <= out_reg; DATA_OUT(31 downto OUTPUTS) <= (others => '0');
+ when others => NACK_OUT <= '1'; ACK_OUT <= '0';
+ end case;
+ end if;
+
end if;
-end process;
+
+
+ end process;
gen_outs : for i in 0 to OUTPUTS-1 generate
output_i(i) <= or_all((INPUT xor invert(i)(INPUTS-1 downto 0)) and enable(i)(INPUTS-1 downto 0));
###################################################################################
#Settings for this project
my $TOPNAME = "trb3_periph_hadesstart"; #Name of top-level entity
-my $lattice_path = '/d/jspc29/lattice/diamond/2.1_x64';
-my $synplify_path = '/d/jspc29/lattice/synplify/F-2012.03-SP1/';
+my $lattice_path = '/d/jspc29/lattice/diamond/3.0_x64';
+my $synplify_path = '/d/jspc29/lattice/synplify/I-2013.09-SP1/';
my $lm_license_file_for_synplify = "27000\@lxcad01.gsi.de";
my $lm_license_file_for_par = "1702\@hadeb05.gsi.de";
###################################################################################
#create full lpf file
system("cp ../base/trb3_periph_ada.lpf workdir/$TOPNAME.lpf");
system("cat currentRelease/trbnet_constraints.lpf >> workdir/$TOPNAME.lpf");
-system("cat currentRelease/tdc_constraints.lpf >> workdir/$TOPNAME.lpf");
+system("cat currentRelease/tdc_constraints_2.lpf >> workdir/$TOPNAME.lpf");
#set -e
#$c=qq|mpartrce -p "../$TOPNAME.p2t" -log "$TOPNAME.log" -o "$TOPNAME.rpt" -pr "$TOPNAME.prf" -tf "$TOPNAME.pt" "|.$TOPNAME.qq|_map.ncd" "$TOPNAME.ncd"|;
# $c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|;
-$c=qq|$lattice_path/ispfpga/bin/lin/par -w -l 5 -i 6 -t 2 -c 0 -e 0 -exp parUseNBR=1:parCDP=0:parCDR=0:parPathBased=OFF $tpmap.ncd $TOPNAME.ncd $TOPNAME.prf|;
+$c=qq|$lattice_path/ispfpga/bin/lin/par -w -l 5 -i 6 -t 3 -c 0 -e 0 -exp parUseNBR=1:parCDP=0:parCDR=0:parPathBased=OFF $tpmap.ncd $TOPNAME.ncd $TOPNAME.prf|;
execute($c);
# IOR IO Timing Report
# $c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|;
------------------------------------------------------------------------------
--TDC settings
- constant NUM_TDC_CHANNELS : integer range 1 to 65 := 5;
- constant NUM_TDC_CHANNELS_POWER2: integer range 0 to 6 := 2; --the nearest power of two, for convenience reasons
+ constant NUM_TDC_CHANNELS : integer range 1 to 65 := 17;
+ constant NUM_TDC_CHANNELS_POWER2: integer range 0 to 6 := 4; --the nearest power of two, for convenience reasons
constant USE_DOUBLE_EDGE : integer := c_YES;
--use only every fourth input as in HPTDC high precision mode
-../tdc_releases/tdc_v1.5.1
\ No newline at end of file
+../tdc_releases/tdc_v1.6/
\ No newline at end of file
add_file -vhdl -lib "work" "currentRelease/Channel.vhd"
add_file -vhdl -lib "work" "currentRelease/Channel_200.vhd"
add_file -vhdl -lib "work" "currentRelease/Encoder_304_Bit.vhd"
-add_file -vhdl -lib "work" "currentRelease/FIFO_36x128_OutReg_Counter.vhd"
+#add_file -vhdl -lib "work" "currentRelease/FIFO_36x128_OutReg_Counter.vhd"
add_file -vhdl -lib "work" "currentRelease/LogicAnalyser.vhd"
add_file -vhdl -lib "work" "currentRelease/Readout.vhd"
add_file -vhdl -lib "work" "currentRelease/ROM4_Encoder.vhd"
add_file -vhdl -lib "work" "currentRelease/ROM_encoder_3.vhd"
add_file -vhdl -lib "work" "currentRelease/ShiftRegisterSISO.vhd"
add_file -vhdl -lib "work" "currentRelease/TDC.vhd"
-#add_file -vhdl -lib "work" "currentRelease/TriggerHandler.vhd"
+add_file -vhdl -lib "work" "currentRelease/TriggerHandler.vhd"
add_file -vhdl -lib "work" "currentRelease/up_counter.vhd"
add_file -vhdl -lib "work" "currentRelease/fallingEdgeDetect.vhd"
add_file -vhdl -lib "work" "currentRelease/risingEdgeDetect.vhd"
add_file -vhdl -lib "work" "../base/cores/FIFO_36x128_OutReg.vhd"
add_file -vhdl -lib "work" "../base/cores/FIFO_DC_36x128_OutReg.vhd"
-add_file -vhdl -lib "work" "currentRelease/Reference_Channel_200.vhd"
-add_file -vhdl -lib "work" "currentRelease/Reference_Channel.vhd"
+#add_file -vhdl -lib "work" "currentRelease/Reference_Channel_200.vhd"
+#add_file -vhdl -lib "work" "currentRelease/Reference_Channel.vhd"
add_file -vhdl -lib work "../../trbnet/special/spi_flash_and_fpga_reload.vhd"
add_file -vhdl -lib "work" "../base/code/input_to_trigger_logic.vhd"
generic map(
PORT_NUMBER => 10,
PORT_ADDRESSES => (0 => x"d000", 1 => x"cf80", 2 => x"d400", 3 => x"c000", 4 => x"c100", 5 => x"c200", 6 => x"c300", 7 => x"c400", 8 => x"c800", 9 => x"cf00", others => x"0000"),
- PORT_ADDR_MASK => (0 => 9, 1 => 6, 2 => 5, 3 => 7, 4 => 5, 5 => 7, 6 => 7, 7 => 7, 8 => 3, 9 => 6, others => 0)
+ PORT_ADDR_MASK => (0 => 9, 1 => 7, 2 => 5, 3 => 7, 4 => 5, 5 => 7, 6 => 7, 7 => 7, 8 => 3, 9 => 6, others => 0)
)
port map(
CLK => clk_100_i,