⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frequency_counter.vhd

📁 晶振频率实时显示在LCD上,包含LCD驱动等程序.
💻 VHD
📖 第 1 页 / 共 2 页
字号:
  -- counters is clean and that no clock cycles are missed or glitches generated.
  --
  -- An asynchronous reset is provided and will be controlled by PicoBlaze using a long
  -- pulse when the counter is disabled. Hence there is no special synchronisation on this control.
  -- 
  ----------------------------------------------------------------------------------------------------------------------------------
  --

  counter_switch_control: process(test_clk)
  begin
    if test_clk'event and test_clk='1' then

      -- Four stage register to ensure synhchronisation of control between clock domains
      ab_switch_delay <= ab_switch_delay(2 downto 0) & ab_switch;
      
      -- Separate enables form switch between counters when control is consistantly high or low.

      case ab_switch_delay(3 downto 1) is

        when "000" => a_count_ce <= '1';
                      b_count_ce <= '0';

        when "111" => a_count_ce <= '0';
                      b_count_ce <= '1';

        when others => a_count_ce <= a_count_ce;
                       b_count_ce <= b_count_ce;

      end case;

    end if;
  end process counter_switch_control;

  -- 32-bit counters 

  test_counter_a: process(test_clk, a_count_rst )
  begin
    if a_count_rst='1' then
       a_count <= X"00000000";
     elsif test_clk'event and test_clk='1' then
      if a_count_ce='1' then
         a_count <= a_count + 1;
       else
         a_count <= a_count;
      end if;
    end if;
  end process test_counter_a;

  test_counter_b: process(test_clk, b_count_rst )
  begin
    if b_count_rst='1' then
       b_count <= X"00000000";
     elsif test_clk'event and test_clk='1' then
      if b_count_ce='1' then
         b_count <= b_count + 1;
       else
         b_count <= b_count;
      end if;
    end if;
  end process test_counter_b;


  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- One Second Timer and Circuit Control
  --
  -- Using the normal 50MHz clock source, this circuit generates a 1 second timer which is used to  
  -- switch the enable from one counter to the other. 
  --
  -- A short delay is then inserted to ensure that the switch has taken place before interrupting the 
  -- PicoBlaze processor. This ensures that the counters are switched and stable for reading etc.
  -- Note: This could cause an issue when very low frequency signals are being measured.
  -- 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  one_second_logic: process(clk_50mhz)
  begin
    if clk_50mhz'event and clk_50mhz='1' then

      if one_second_count=49999999 then      --divide by 50,000,000 is 1s
        one_second_count <= 0;
        one_second_pulse <= '1';
       else
        one_second_count <= one_second_count + 1;
        one_second_pulse <= '0';
      end if;

      -- delay of 100 clock cycles before generating interrupt 
      interrupt_delay <= interrupt_delay(98 downto 0) & one_second_pulse;

      -- processor interrupt waits for an acknowledgement
      if interrupt_ack='1' then
         interrupt <= '0';
        elsif interrupt_delay(99) ='1' then
         interrupt <= '1';
        else
         interrupt <= interrupt;
      end if;

      -- counter selection switch toggles each second
      if one_second_pulse='1' then
        ab_switch <= not ab_switch;
      end if;

    end if;

  end process one_second_logic;

  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- KCPSM3 and the program memory used for capturing data from the counters
  ----------------------------------------------------------------------------------------------------------------------------------
  --

  processor: kcpsm3
    port map(      address => address,
               instruction => instruction,
                   port_id => port_id,
              write_strobe => write_strobe,
                  out_port => out_port,
               read_strobe => read_strobe,
                   in_port => in_port,
                 interrupt => interrupt,
             interrupt_ack => interrupt_ack,
                     reset => reset,
                       clk => clk_50mhz);
 
  program_rom: fc_ctrl
    port map(      address => address,
               instruction => instruction,
                proc_reset => reset,        --JTAG Loader version
                       clk => clk_50mhz);

  --reset <= '0';  --When using normal version
  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Capture processor input ports 
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  --
  -- The inputs are connected via a pipelined multiplexer
  --

  input_ports: process(clk_50mhz)
  begin
    if clk_50mhz'event and clk_50mhz='1' then

      case port_id(7 downto 4) is

        -- read A-counter for addresses 00, 10, 20 and 30 hex
        when "0000" =>    in_port <= a_count(7 downto 0);  
        when "0001" =>    in_port <= a_count(15 downto 8);  
        when "0010" =>    in_port <= a_count(23 downto 16);  
        when "0011" =>    in_port <= a_count(31 downto 24);  

        -- read B-counter for addresses 40, 50, 60 and 70 hex
        when "0100" =>    in_port <= b_count(7 downto 0);  
        when "0101" =>    in_port <= b_count(15 downto 8);  
        when "0110" =>    in_port <= b_count(23 downto 16);  
        when "0111" =>    in_port <= b_count(31 downto 24);  

        -- read slide switches and counter circuit status at address 80 hex
        when "1000" =>    in_port <= "000" & ab_switch & sw;

        -- read LCD data at address 90 hex
        when "1001" =>    in_port <= lcd_d & "0000";

        -- Don't care used to ensure minimum logic
        when others =>    in_port <= "XXXXXXXX";  

      end case;

    end if;

  end process input_ports;


  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Capture processor output ports 
  ----------------------------------------------------------------------------------------------------------------------------------
  --

  output_ports: process(clk_50mhz)
  begin

    if clk_50mhz'event and clk_50mhz='1' then
      if write_strobe='1' then
        
        -- LED register at address 01 hex 
        if port_id(0)='1' then
          led <= out_port;
        end if;

        -- Counter reset controls at address 02 hex 
        if port_id(1)='1' then
          a_count_rst <= out_port(0);
          b_count_rst <= out_port(1);
        end if;

        -- LCD data output and controls at address 04 hex.

        if port_id(2)='1' then
          lcd_output_data <= out_port(7 downto 4);
          lcd_drive <= out_port(3);  
          lcd_rs <= out_port(2);
          lcd_rw_control <= out_port(1);
          lcd_e <= out_port(0);
        end if;

        -- Source selection and control at address 08 hex.

        if port_id(3)='1' then
          source_control <= out_port;
        end if;

      end if;
    end if; 

  end process output_ports;

  --
  --
  ----------------------------------------------------------------------------------------------------------------------------------
  -- LCD interface  
  ----------------------------------------------------------------------------------------------------------------------------------
  --
  -- The 4-bit data port is bidirectional.
  -- lcd_rw is '1' for read and '0' for write 
  -- lcd_drive is like a master enable signal which prevents either the 
  -- FPGA outputs or the LCD display driving the data lines.
  --
  --Control of read and write signal
  lcd_rw <= lcd_rw_control and lcd_drive;

  --use read/write control to enable output buffers.
  lcd_d <= lcd_output_data when (lcd_rw_control='0' and lcd_drive='1') else "ZZZZ";

  ----------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------------------------------------------------------

end Behavioral;

------------------------------------------------------------------------------------------------------------------------------------
--
-- END OF FILE frequency_counter.vhd
--
------------------------------------------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -