---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 16:07:58 03/15/2008 -- Design Name: -- Module Name: Counter_16times48Bit - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity Counter_64times48Bit is Port ( counter_en : in STD_LOGIC_VECTOR (63 downto 0); clk : in STD_LOGIC; -- runs on Spartan 3 with up to 105 Mhz readout_req : in STD_LOGIC; reset : in STD_LOGIC; readout_done : out STD_LOGIC; -- indicates valid data on the counter_value port readout_counter_addr : in STD_LOGIC_VECTOR (5 downto 0); counter_value : out STD_LOGIC_VECTOR (47 downto 0)); end Counter_64times48Bit; architecture Behavioral of Counter_64times48Bit is component RAM port ( addra: IN std_logic_VECTOR(5 downto 0); addrb: IN std_logic_VECTOR(5 downto 0); clka: IN std_logic; clkb: IN std_logic; dina: IN std_logic_VECTOR(47 downto 0); dinb: IN std_logic_VECTOR(47 downto 0); douta: OUT std_logic_VECTOR(47 downto 0); doutb: OUT std_logic_VECTOR(47 downto 0); sinita: IN std_logic; sinitb: IN std_logic; wea: IN std_logic; web: IN std_logic); end component; -- Synplicity black box declaration attribute syn_black_box : boolean; attribute syn_black_box of RAM: component is true; component Counter_6Bit port ( clk: IN std_logic; ce: IN std_logic; aclr: IN std_logic; q: OUT std_logic_VECTOR(5 downto 0)); end component; attribute syn_black_box of Counter_6Bit: component is true; component LATCH_6Bit port ( D: IN std_logic_VECTOR(5 downto 0); Q: OUT std_logic_VECTOR(5 downto 0); CLK: IN std_logic; CE: IN std_logic; SCLR: IN std_logic); end component; attribute syn_black_box of LATCH_6Bit: component is true; component MUX_64times1Bit_to1Bit port ( M: IN std_logic_VECTOR(63 downto 0); S: IN std_logic_VECTOR(5 downto 0); O: OUT std_logic); end component; -- Synplicity black box declaration attribute syn_black_box of MUX_64times1Bit_to1Bit: component is true; component ALU_adder port ( A: IN std_logic_VECTOR(5 downto 0); B: IN std_logic_VECTOR(47 downto 0); S: OUT std_logic_VECTOR(47 downto 0)); end component; -- Synplicity black box declaration attribute syn_black_box of ALU_adder: component is true; signal sig0, sig1, sig2, sig3, sig4, sig5 : std_logic_vector(63 downto 0); signal sig00, sig01, sig02, sig03, sig04, sig05 : std_logic_vector(63 downto 0); signal sig17 : std_logic; signal sig34, sig35 : std_logic_vector(5 downto 0); signal sig36, sig37, sig38, sig40 : std_logic_vector(47 downto 0):=X"000000000000"; signal sig43, sig44: std_logic; -- controlling signals of the whole counter module signal ctrl_signal: std_logic_vector(5 downto 0); signal ctrl_minus1_signal: std_logic_vector(5 downto 0); signal ctrl_plus1_signal: std_logic_vector(5 downto 0); signal int1, int2, int3: integer range 0 to 63; -- preventing undefinded values written to ram signal sig41, sig42: std_logic := '0'; -- state machine for readout signal state, next_state : std_logic_vector(2 downto 0); signal sig39 : std_logic; begin -- couner i inputstage: for i in 0 to 63 generate inputstage_incounter : Counter_6Bit port map ( clk => clk, ce => counter_en(i), aclr => sig43, q(0) => sig0(i), q(1) => sig1(i), q(2) => sig2(i), q(3) => sig3(i), q(4) => sig4(i), q(5) => sig5(i)); inputstage_latch : LATCH_6Bit port map ( D(0) => sig0(i), D(1) => sig1(i), D(2) => sig2(i), D(3) => sig3(i), D(4) => sig4(i), D(5) => sig5(i), Q(0) => sig00(i), Q(1) => sig01(i), Q(2) => sig02(i), Q(3) => sig03(i), Q(4) => sig04(i), Q(5) => sig05(i), CLK => CLK, CE => sig17, SCLR => reset); end generate; -- controlling we of counter memory process(reset, clk, ctrl_signal) begin if ctrl_signal = "111111" then sig17 <= '1'; else sig17 <= '0'; end if; end process; -- controlling aclr of counter -- clear in the half clk'cycle after the we of the memory process(reset, clk, sig17) begin if reset='1' then sig44 <= '0'; elsif clk'event and clk='1' then sig44 <= sig17; end if; end process; sig43 <= sig44 and clk; -- MUX for ALU -- Bit 0 Mux_Alu_0Bit : MUX_64times1Bit_to1Bit port map ( M => sig00, S => ctrl_signal, O => sig34(0)); -- Bit 1 Mux_Alu_1Bit : MUX_64times1Bit_to1Bit port map ( M => sig01, S => ctrl_signal, O => sig34(1)); -- Bit 2 Mux_Alu_2Bit : MUX_64times1Bit_to1Bit port map ( M => sig02, S => ctrl_signal, O => sig34(2)); -- Bit 3 Mux_Alu_3Bit : MUX_64times1Bit_to1Bit port map ( M => sig03, S => ctrl_signal, O => sig34(3)); -- Bit 4 Mux_Alu_4Bit : MUX_64times1Bit_to1Bit port map ( M => sig04, S => ctrl_signal, O => sig34(4)); -- Bit 5 Mux_Alu_5Bit : MUX_64times1Bit_to1Bit port map ( M => sig05, S => ctrl_signal, O => sig34(5)); -- pipeline FlipFlop from in_counters process(reset, sig34, clk) begin if (clk'event and clk='1') then sig35 <= sig34; end if; end process; -- pipeline FlipFlops from Ram_memory process(reset, sig37, clk) begin if (clk'event and clk = '1') then sig36 <= sig37; end if; end process; -- ALU ALU : ALU_adder port map ( A => sig35, B => sig36, S => sig38); -- Counter Ram counter_ram : RAM port map ( addra => ctrl_minus1_signal, addrb => ctrl_plus1_signal, clka => clk, clkb => clk, dina => sig38, dinb => (others => '0'), douta => open, doutb => sig40, sinita => reset, sinitb => reset, wea => sig41, web => '0'); -- RAM outputs are XXXXX after startup -- prevent these values from being written to RAM process(reset, sig40) begin if reset='1' then sig37 <= X"000000000000"; else sig37 <= sig40; end if; end process; process(reset, clk, sig42) begin if clk'event and clk='1' then sig41 <= sig42; end if; end process; sig42 <= reset or sig41; -- readout Ram readout_ram : RAM port map ( addra => ctrl_signal, addrb => readout_counter_addr, clka => clk, clkb => clk, dina => sig40, dinb => (others => '0'), douta => open, doutb => counter_value, sinita => reset, sinitb => reset, wea => sig39, web => '0'); -- controll engine (two simple counter) process(reset, clk, int1) begin if clk'event and clk='1' then if reset = '1' then int1 <= 63; else int1 <= int1 + 1; end if; end if; end process; process(reset, clk, int2) begin if clk'event and clk='1' then if reset = '1' then int2 <= 62; else int2 <= int2 + 1; end if; end if; end process; process(reset, clk, int3) begin if clk'event and clk='1' then if reset = '1' then int3 <= 0; else int3 <= int3 + 1; end if; end if; end process; ctrl_signal <= CONV_STD_LOGIC_VECTOR(int1,6); ctrl_minus1_signal <= CONV_STD_LOGIC_VECTOR(int2,6); ctrl_plus1_signal <= CONV_STD_LOGIC_VECTOR(int3,6); -- state machine controlling readout of counters -- state switching process(state, ctrl_signal, readout_req) begin next_state <= (others => '0'); -- reset state if state = "000" then next_state <= "001"; end if; -- wait readout_req state if state = "001" then if (readout_req = '0') then next_state <= "001"; end if; if (readout_req = '1') then next_state <= "010"; end if; end if; -- wait ctrl = 15 state if state = "010" then if (ctrl_signal = "1111") then next_state <= "011"; else next_state <= "010"; end if; end if; -- copy state if state = "011" then if (ctrl_signal = "1111") then next_state <= "100"; else next_state <= "011"; end if; end if; -- Done state (valid data on the counter_value port) if state = "100" then if (readout_req = '0') then next_state <= "001"; else next_state <= "100"; end if; end if; end process; -- output process(state) begin -- standard values sig39 <= '0'; -- we signal for readout ram readout_done <= '0'; if state ="000" then sig39 <= '0'; readout_done <= '0'; end if; if state ="001" then sig39 <= '0'; readout_done <= '0'; end if; if state = "010" then sig39 <= '0'; readout_done <= '0'; end if; if state ="011" then sig39 <= '1'; readout_done <= '0'; end if; if state ="100" then sig39 <= '0'; readout_done <= '1'; end if; end process; -- state transmission register process (clk, reset) begin if reset = '1' then state <= "000"; elsif clk'event and clk = '1' then state <= next_state; end if; end process; end Behavioral;