--Pulsers: 0 - 15: OUTP, 16 - 19: OUTP_FAN, 20 - 29: OUTP_ANA
---0x00 Pulser enable
---0x01 Pulser invert
---0x10 Pulser control strobe
+--0x000 - 0x00f Pulser enable
+--0x010 - 0x01f Pulser invert
+--0x040 - 0x041 Analog configuration (Bit0-4: SEL, Bit 8-9 SELO
+--0x0f0 Pulser control strobe
---0x40 - 0x41 Analog configuration (Bit0-4: SEL, Bit 8-9 SELO
---0x80 - 0x9f pulser period, 5 ns
---0xa0 - 0xbf pulse length, 1.25 ns (only multiples of 5ns supported)
---0xc0 - 0xdf pulser offset, 5 ns
+--0x100 - 0x1ff pulser period, 5 ns
+--0x200 - 0x2ff pulse length, 1.25 ns (only multiples of 5ns supported)
+--0x300 - 0x3ff pulser offset, 5 ns
architecture pulser_arch of pulser is
+constant channel_num : integer := 48;
+constant channel_reg_num : integer := 64;
signal clk_slow_left, clk_slow_right : std_logic;
-type arr_32unsigned_t is array(0 to 31) of unsigned(31 downto 0);
+type arr_32unsigned_t is array(0 to channel_num-1) of unsigned(31 downto 0);
+type arr_1920slv_t is array(0 to 19) of std_logic_vector(15 downto 0);
signal period : arr_32unsigned_t;
signal length : arr_32unsigned_t;
signal offset : arr_32unsigned_t;
-signal timer : arr_32unsigned_t;
+signal use_add: arr_1920slv_t;
signal ana1_in_select, ana2_in_select : std_logic_vector(3 downto 0);
signal ana1_out_select, ana2_out_select: std_logic_vector(1 downto 0);
signal control_strobes : std_logic_vector(31 downto 0);
-signal pulser_enable : std_logic_vector(31 downto 0);
-signal pulser_invert : std_logic_vector(31 downto 0);
+signal pulser_enable : std_logic_vector(channel_reg_num-1 downto 0);
+signal pulser_invert : std_logic_vector(channel_reg_num-1 downto 0);
signal pulser_reset : std_logic;
signal next_pulser_reset : std_logic;
-- type pulse_ddr_t is array(0 to 31) of std_logic_vector(3 downto 0);
-- signal pulse : pulse_ddr_t;
-
+type d_t is array(0 to 3) of std_logic_vector(channel_num-1 downto 0);
type dleft_t is array(0 to 3) of std_logic_vector(19 downto 0);
type dright_t is array(0 to 3) of std_logic_vector(9 downto 0);
-signal data_left : dleft_t;
+type dadd_t is array(0 to 3) of std_logic_vector(7 downto 0);
+signal data_all : d_t;
+signal data_left : dleft_t;
signal data_right : dright_t;
-
+signal data_add : dadd_t;
begin
FREQUENCY => period(n)(23 downto 0),
PULSE_WIDTH => length(n)(23 downto 0),
OFFSET => offset(n)(23 downto 0),
- INVERT => pulser_invert(n),
ENABLE => pulser_enable(n),
- PULSE(0) => data_left(0)(n),
- PULSE(1) => data_left(1)(n),
- PULSE(2) => data_left(2)(n),
- PULSE(3) => data_left(3)(n)
+ PULSE(0) => data_all(0)(n),
+ PULSE(1) => data_all(1)(n),
+ PULSE(2) => data_all(2)(n),
+ PULSE(3) => data_all(3)(n)
);
end generate;
FREQUENCY => period(n+20)(23 downto 0),
PULSE_WIDTH => length(n+20)(23 downto 0),
OFFSET => offset(n+20)(23 downto 0),
- INVERT => pulser_invert(n+20),
ENABLE => pulser_enable(n+20),
- PULSE(0) => data_right(0)(n),
- PULSE(1) => data_right(1)(n),
- PULSE(2) => data_right(2)(n),
- PULSE(3) => data_right(3)(n)
+ PULSE(0) => data_all(0)(n+20),
+ PULSE(1) => data_all(1)(n+20),
+ PULSE(2) => data_all(2)(n+20),
+ PULSE(3) => data_all(3)(n+20)
+ );
+end generate;
+
+multi_ch_pulser_addleft : for n in 0 to 7 generate
+ pulser : entity work.single_channel_pulser
+ port map (
+ CLK => clk_slow_left,
+ RESET => pulser_reset,
+ FREQUENCY => period(n+32)(23 downto 0),
+ PULSE_WIDTH => length(n+32)(23 downto 0),
+ OFFSET => offset(n+32)(23 downto 0),
+ ENABLE => pulser_enable(n+32),
+ PULSE(0) => data_all(0)(n+32),
+ PULSE(1) => data_all(1)(n+32),
+ PULSE(2) => data_all(2)(n+32),
+ PULSE(3) => data_all(3)(n+32)
);
end generate;
+gen_left : for i in 0 to 19 generate
+ process begin
+ wait until rising_edge(clk_slow_left);
+ data_left(0)(i) <= (data_all(0)(i) or or_all(data_add(0)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i);
+ data_left(1)(i) <= (data_all(1)(i) or or_all(data_add(1)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i);
+ data_left(2)(i) <= (data_all(2)(i) or or_all(data_add(2)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i);
+ data_left(3)(i) <= (data_all(3)(i) or or_all(data_add(3)(7 downto 0) and use_add(i)(7 downto 0))) xor pulser_invert(i);
+ end process;
+end generate;
+
+gen_right : for i in 20 to 29 generate
+ data_right(0)(i-20) <= data_all(0)(i) xor pulser_invert(i) when rising_edge(clk_slow_right);
+ data_right(1)(i-20) <= data_all(1)(i) xor pulser_invert(i) when rising_edge(clk_slow_right);
+ data_right(2)(i-20) <= data_all(2)(i) xor pulser_invert(i) when rising_edge(clk_slow_right);
+ data_right(3)(i-20) <= data_all(3)(i) xor pulser_invert(i) when rising_edge(clk_slow_right);
+end generate;
+data_add(0) <= data_all(0)(39 downto 32) when rising_edge(clk_slow_left);
+data_add(1) <= data_all(1)(39 downto 32) when rising_edge(clk_slow_left);
+data_add(2) <= data_all(2)(39 downto 32) when rising_edge(clk_slow_left);
+data_add(3) <= data_all(3)(39 downto 32) when rising_edge(clk_slow_left);
--- gen_outp : for n in 0 to 15 generate
--- OUTP(n+1) <= data_left(0)(n);
--- end generate;
---
--- gen_outp_fan : for n in 0 to 3 generate
--- OUTP_FAN(n) <= data_left(0)(n+16);
--- end generate;
--- gen_outp_ana : for n in 0 to 9 generate
--- OUTP_ANA(n) <= pulse(n+20)(0);
--- end generate;
THE_LEFT_DDR : entity work.ddr_20
port map(
-------------------------------------------------
- proc_ctrlbus : process begin
+ proc_ctrlbus : process
+ variable channel : integer range 0 to 255;
+ begin
wait until rising_edge(SYSCLK);
BUS_TX.ack <= '0'; BUS_TX.nack <= '0'; BUS_TX.unknown <= '0';
control_strobes <= (others => '0');
next_pulser_reset <= '0';
pulser_reset <= RESET or next_pulser_reset;
+ channel := to_integer(unsigned(BUS_RX.addr(7 downto 0)));
if BUS_RX.read = '1' then
BUS_TX.ack <= '1';
- if BUS_RX.addr(7 downto 5) = "100" then
- BUS_TX.data <= std_logic_vector(period(to_integer(unsigned(BUS_RX.addr(4 downto 0)))));
- elsif BUS_RX.addr(7 downto 5) = "101" then
- BUS_TX.data <= std_logic_vector(length(to_integer(unsigned(BUS_RX.addr(4 downto 0)))));
- elsif BUS_RX.addr(7 downto 5) = "110" then
- BUS_TX.data <= std_logic_vector(offset(to_integer(unsigned(BUS_RX.addr(4 downto 0)))));
- elsif BUS_RX.addr(7 downto 0) = x"00" then
- BUS_TX.data <= pulser_enable;
- elsif BUS_RX.addr(7 downto 0) = x"01" then
- BUS_TX.data <= pulser_invert;
- elsif BUS_RX.addr(7 downto 0) = x"40" then
+ if BUS_RX.addr(11 downto 8) = x"1" and channel < channel_num then
+ BUS_TX.data <= std_logic_vector(period(channel));
+ elsif BUS_RX.addr(11 downto 8) = x"2" and channel < channel_num then
+ BUS_TX.data <= std_logic_vector(length(channel));
+ elsif BUS_RX.addr(11 downto 8) = x"3" and channel < channel_num then
+ BUS_TX.data <= std_logic_vector(offset(channel));
+ elsif BUS_RX.addr(11 downto 8) = x"4" and channel < 20 then
+ BUS_TX.data <= x"0000" & std_logic_vector(use_add(channel));
+ elsif BUS_RX.addr(11 downto 0) = x"000" then
+ BUS_TX.data <= pulser_enable(31 downto 0);
+ elsif BUS_RX.addr(11 downto 0) = x"001" then
+ BUS_TX.data <= pulser_enable(63 downto 32);
+ elsif BUS_RX.addr(11 downto 0) = x"010" then
+ BUS_TX.data <= pulser_invert(31 downto 0);
+ elsif BUS_RX.addr(11 downto 0) = x"011" then
+ BUS_TX.data <= pulser_invert(63 downto 32);
+ elsif BUS_RX.addr(11 downto 0) = x"040" then
BUS_TX.data(3 downto 0) <= ana1_in_select;
BUS_TX.data(9 downto 8) <= ana1_out_select;
- elsif BUS_RX.addr(7 downto 0) = x"41" then
+ elsif BUS_RX.addr(11 downto 0) = x"041" then
BUS_TX.data(3 downto 0) <= ana2_in_select;
BUS_TX.data(9 downto 8) <= ana2_out_select;
else
elsif BUS_RX.write = '1' then
BUS_TX.ack <= '1';
- if BUS_RX.addr(7 downto 5) = "100" then
- period(to_integer(unsigned(BUS_RX.addr(4 downto 0)))) <= unsigned(BUS_RX.data);
+ if BUS_RX.addr(11 downto 8) = x"1" and channel < channel_num then
+ period(channel) <= unsigned(BUS_RX.data);
next_pulser_reset <= '1';
- elsif BUS_RX.addr(7 downto 5) = "101" then
- length(to_integer(unsigned(BUS_RX.addr(4 downto 0)))) <= unsigned(BUS_RX.data);
+ elsif BUS_RX.addr(11 downto 8) = x"2" and channel < channel_num then
+ length(channel) <= unsigned(BUS_RX.data);
next_pulser_reset <= '1';
- elsif BUS_RX.addr(7 downto 5) = "110" then
- offset(to_integer(unsigned(BUS_RX.addr(4 downto 0)))) <= unsigned(BUS_RX.data);
+ elsif BUS_RX.addr(11 downto 8) = x"3" and channel < channel_num then
+ offset(channel) <= unsigned(BUS_RX.data);
next_pulser_reset <= '1';
- elsif BUS_RX.addr(7 downto 0) = x"00" then
- pulser_enable <= BUS_RX.data;
- elsif BUS_RX.addr(7 downto 0) = x"01" then
- pulser_invert <= BUS_RX.data;
- elsif BUS_RX.addr(7 downto 0) = x"10" then
+ elsif BUS_RX.addr(11 downto 8) = x"4" and channel < 20 then
+ use_add(channel) <= BUS_RX.data(15 downto 0);
+ elsif BUS_RX.addr(11 downto 0) = x"000" then
+ pulser_enable(31 downto 0) <= BUS_RX.data;
+ elsif BUS_RX.addr(11 downto 0) = x"001" then
+ pulser_enable(63 downto 32) <= BUS_RX.data;
+ elsif BUS_RX.addr(11 downto 0) = x"010" then
+ pulser_invert(31 downto 0) <= BUS_RX.data;
+ elsif BUS_RX.addr(11 downto 0) = x"011" then
+ pulser_invert(63 downto 32) <= BUS_RX.data;
+ elsif BUS_RX.addr(11 downto 0) = x"0f0" then
control_strobes <= BUS_RX.data;
pulser_reset <= BUS_RX.data(0);
- elsif BUS_RX.addr(7 downto 0) = x"40" then
+ elsif BUS_RX.addr(11 downto 0) = x"040" then
ana1_in_select <= BUS_RX.data(3 downto 0);
ana1_out_select <= BUS_RX.data(9 downto 8);
- elsif BUS_RX.addr(7 downto 0) = x"41" then
+ elsif BUS_RX.addr(11 downto 0) = x"041" then
ana2_in_select <= BUS_RX.data(3 downto 0);
ana2_out_select <= BUS_RX.data(9 downto 8);
else
BLOCK NET "THE_PULSER/offset*" ;
BLOCK NET "THE_PULSER/pulser_reset*" ;
BLOCK NET "THE_PULSER/pulser_enable*" ;
+BLOCK NET "THE_PULSER/use_add*" ;
CLOCK_TO_OUT "OUTP*" 30 NS CLKNET = "THE_PULSER/THE_LEFT_DDR/clkop";
CLOCK_TO_OUT "OUTP*" 30 NS CLKNET = "THE_PULSER/THE_RIGHT_DDR/clkop";
# REGION "REGION_PULSER_LEFT" "R2C2D" 114 36 DEVSIZE;
-UGROUP "Pulser_left" BBOX 114 20
+UGROUP "Pulser_left" BBOX 114 30
BLKNAME THE_PULSER/multi_ch_pulser_left.0.pulser
BLKNAME THE_PULSER/multi_ch_pulser_left.1.pulser
BLKNAME THE_PULSER/multi_ch_pulser_left.2.pulser
BLKNAME THE_PULSER/multi_ch_pulser_left.17.pulser
BLKNAME THE_PULSER/multi_ch_pulser_left.18.pulser
BLKNAME THE_PULSER/multi_ch_pulser_left.19.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.0.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.1.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.2.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.3.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.4.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.5.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.6.pulser
+ BLKNAME THE_PULSER/multi_ch_pulser_addleft.7.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.8.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.9.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.10.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.11.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.12.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.13.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.14.pulser
+# BLKNAME THE_PULSER/multi_ch_pulser_addleft.15.pulser
;
LOCATE UGROUP "Pulser_left" SITE "R2C2D";
# REGION "REGION_PULSER_RIGHT" "R2C147D" 114 35 DEVSIZE;
-UGROUP "Pulser_right" BBOX 114 20
+UGROUP "Pulser_right" BBOX 114 30
BLKNAME THE_PULSER/multi_ch_pulser_right.0.pulser
BLKNAME THE_PULSER/multi_ch_pulser_right.1.pulser
BLKNAME THE_PULSER/multi_ch_pulser_right.2.pulser
BLKNAME THE_PULSER/multi_ch_pulser_right.8.pulser
BLKNAME THE_PULSER/multi_ch_pulser_right.9.pulser
;
-LOCATE UGROUP "Pulser_right" SITE "R2C152D";
\ No newline at end of file
+LOCATE UGROUP "Pulser_right" SITE "R2C142D";
\ No newline at end of file