سلام.
لطفا منو در نوشتن یک کد vhdl برای جمع دو فرکانس ورودی که به صورت کلاکند کمک کنید.
:cry2: :cry2: :cry2:
لطفا منو در نوشتن یک کد vhdl برای جمع دو فرکانس ورودی که به صورت کلاکند کمک کنید.


-- -- -- AUTO-RANGING Single Chip Frequency Counter -- -- This is a synthesizable model of an autoranging frequency counter. -- The overall frequency counting coverage is from DC~9.999MHz. There are -- four ranges, which are "auto" selected: -- -- frequency GATE width -- DC-9999Hz, 1 sec -- 10.00KHz-99.99KHz, .1 sec -- 100.0KHz-999.9KHz. .01 sec -- 1.000MHz-9.999MHz .001 sec -- -- -- Top level chip-interface is as follows: -- -- Input: -- sys_rs_l std_logic asynchronous actuve low reset -- ref_clk std_logic 10MHz reference clock input -- Funknown std_logic reference clock input from DC - 10Mhz -- -- Output -- gate0_l std_logic one's place 7segment LED common anode gate -- gate1_l std_logic ten's place 6segment LED common anode gate -- gate2_l std_logic hundred's place 7segment LED common anode gate -- gate3_l std_logic thousand's place 6segment LED common anode gate -- -- -- -- OPERATION -- -- This frequency counter is based on the premise of counting the incoming unknown -- frequency's rising edge for a predetermined fixed amount of time, or GATE. -- If the counter overflow , then the presently selected GATE is too wide, so the -- next shortest GATE width is selected. This switching is done immediately, so -- that no time is wasted in waiting for the GATE to turn off. -- The measured frequency data is then displayed onto a multiplexed 4 digit 7segment -- LED display. Since the LED display is refhreshed at 100KHz, a fixed time interval -- is waited before the next conversion cycle. This gives the display a chance to -- "update" all the segments. -- -- -- STATE TRANSITION -- -- /------\ -- | | -- | IDLE -- | | -- | /-- | -- | | \ V overflow=HI -- | | GATE_ON ----------------> OVERFLOW -- | \--/ | | -- | | | -- | | gate_counter=N | -- | | | -- | V | -- | DISPLAY | -- | | | -- | | | -- | /-- | | -- | | \ V | -- | | DELAY <----------------------/ -- | \--/ | -- \-------/ -- gate_counter=N2 -- -- IDLE state -- This state hold the BCD counter in reset state then transitions -- into the next state, GATE_ON. The BCD counter must be hold into reset -- in order not to accumulate from the previous count cycle -- -- GATE_ON state -- In this state, the BCD counter is allowed to start counting by asserting -- the signal 'GATE'. Also, an internal timer is started which times -- the time for which the GATE should be on for. Go to next state when -- the timer hits the expected tick count -- -- DISPLAY state -- In this state, the 4 digit muxed display is "refreshed", that is loaded with -- the new data from the BCD counter -- -- DELAY state -- This state simply waits for a fixed delay. This fixed delay is required -- in order to give the display a chance to cycle through the segment refreshing -- -- OVERFLOW state -- This state enters when the BCD counter overflows with the given GATE. This -- means that the GATE is too long, so the next shortest gate length is chosen -- and the measurement starts over again. -- -- -- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; ENTITY freq_counter IS PORT ( sys_rst_l : IN std_logic; ref_clk : IN std_logic; Funknown : IN std_logic; gate0_l : OUT std_logic; gate1_l : OUT std_logic; gate2_l : OUT std_logic; gate3_l : OUT std_logic; digit_out_l : OUT std_logic_vector (7 downto 0); -- debug d_gate : OUT std_logic; d_gate_cnt_limit : OUT integer range 0 to 10000000; d_f_counter_count_out : OUT std_logic_vector (15 downto 0); d_f_overflow : OUT std_logic ); END freq_counter; ARCHITECTURE FREQ_COUNTER_RTL OF freq_counter IS -- Declare the 4 digit muxed 7segment LED display DISPLAY COMPONENT disp4_muxed PORT ( clk_disp : IN std_logic; clk_ref : IN std_logic; sys_rst_l : IN std_logic; data_in : IN std_logic_vector (15 downto 0); dp_in : IN std_logic_vector ( 1 downto 0); load : IN std_logic; gate0_l : OUT std_logic; gate1_l : OUT std_logic; gate2_l : OUT std_logic; gate3_l : OUT std_logic; digit_out_l: OUT std_logic_vector (7 downto 0) -- MSB=dp,g,f,.., LSB=a ); END COMPONENT; -- Declare the 4 digit BCD counter COMPONENT bcdcounter4 PORT ( Funknown : IN std_logic; sys_rst_l : IN std_logic; GATE : IN std_logic; ready : OUT std_logic; data_out : OUT std_logic_vector (15 downto 0); overflow : OUT std_logic ); END COMPONENT; CONSTANT HIGH : std_logic := '1'; CONSTANT LOW : std_logic := '0'; TYPE allowed_states IS (idle, gate_on, display, delay, overflow); SIGNAL state : allowed_states; SIGNAL display_load : std_logic; SIGNAL gate : std_logic; SIGNAL f_ready : std_logic; SIGNAL f_counter_count_out : std_logic_vector (15 downto 0); SIGNAL f_overflow : std_logic; SIGNAL clk_100Khz : std_logic; SIGNAL scaler : std_logic_vector (2 downto 0); SIGNAL auto_scale : std_logic_vector (2 downto 0); SIGNAL gate_counter : integer RANGE 0 TO 10000000; -- 24 bits SIGNAL GATE_CNT_LIMIT : integer RANGE 0 TO 10000000; SIGNAL cnt_ena : std_logic; SIGNAL counter_reset : std_logic; -- RTL BEGINS HERE BEGIN -- debug signals (turn them off if yuo do not need them -- these were on for helping simulation) d_gate <= gate; d_gate_cnt_limit <= gate_cnt_limit; d_f_counter_count_out <= f_counter_count_out; d_f_overflow <= f_overflow; -- Connect the subcomponenet THE_DISPLAY: disp4_muxed PORT MAP (clk_disp => clk_100Khz, clk_ref => ref_clk, sys_rst_l => sys_rst_l, data_in => f_counter_count_out, dp_in => NOT (auto_scale(1 downto 0)), load => display_load, gate0_l => gate0_l, gate1_l => gate1_l, gate2_l => gate2_l, gate3_l => gate3_l, digit_out_l => digit_out_l ); -- COnnect the 4 digit BCD counter THE_COUNTER: bcdcounter4 PORT MAP (Funknown => Funknown, sys_rst_l => counter_reset, GATE => gate, ready => f_ready, data_out => f_counter_count_out, overflow => f_overflow ); -- CONTROLLER STATE MACHINE -- SM: PROCESS (sys_rst_l, ref_clk) BEGIN -- on reset clear the world IF (sys_rst_l=LOW) THEN state <= idle; scaler <= "000"; auto_scale <= "000"; gate <= LOW; cnt_ena <= LOW; display_load <= LOW; counter_reset <= LOW; -- reset the fcounter -- on every rising edge of ref_clk (10MHz) ELSIF (ref_clk=HIGH and ref_clk'EVENT) THEN CASE (state) IS -- IDLE state -- goto next state WHEN idle => state <= gate_on; counter_reset <= LOW; -- reset the fcounter -- GATE_ON state -- turn on the "gate" which the BCD counter will count clk pulses WHEN gate_on => counter_reset <= HIGH; gate <= HIGH; -- GATE is high cnt_ena <= HIGH; -- GATE counter is enabled -- if the gate counter reaches the gate time limit, goto next state IF (gate_counter=GATE_CNT_LIMIT) THEN gate <= LOW; -- turn off gate cnt_ena <= LOW; -- turn off gate counter state <= display; auto_scale <= "000"; -- if the BCD counter has overflowed, go to overflow state ELSIF (f_overflow=HIGH) THEN state <= overflow; END IF; -- DISPLAY state -- go and "refresh" the display WHEN display => display_load <= HIGH; -- load the display with the recent BCD counter state <= delay; -- DELAY state -- wait here for a bit, to give the muxed LED display a chance -- to go through its mux cycle WHEN delay => scaler <= "100"; -- set delay to be just the display delay cnt_ena <= HIGH; -- enable gate counter display_load <= LOW; -- stop with the loading.. -- when the counter has hit the time limit go to next state IF (gate_counter=GATE_CNT_LIMIT) THEN cnt_ena <= LOW; -- turn off gate counter scaler <= auto_scale; state <= idle; END IF; -- OVERFLOW state -- when the BCD counter has overflowed with the current gate width, -- select the next shortest gate (1sec, .1sec, .01sec and .001 sec) -- and remeasure it. WHEN overflow => CASE (auto_scale) IS WHEN "000" => auto_scale <= "001"; WHEN "001" => auto_scale <= "010"; WHEN "010" => auto_scale <= "011"; WHEN "011" => auto_scale <= "011"; WHEN OTHERS => NULL; END CASE; gate <= LOW; -- turn off gate cnt_ena <= LOW; state <= delay; END CASE; END IF; END PROCESS SM; -- GATE WIDTH SELECTOR -- This process selects the width of the GATE signal, by selecting -- the ticks which will equal the reference time. The ticks is -- based on 100nS period (10MHz). IF you're using a differenct clock, you need to -- change the below 5 values PROCESS (scaler) BEGIN CASE (scaler) IS WHEN "000" => GATE_CNT_LIMIT <= 10000000; -- 10 million cycles per GATE of 1 SECOND WHEN "001" => GATE_CNT_LIMIT <= 1000000; -- 1 million cycles per GATE of .1 SECOND WHEN "010" => GATE_CNT_LIMIT <= 100000; -- 100K cycles per GATE of .01 SECOND WHEN "011" => GATE_CNT_LIMIT <= 10000; -- 10K cycles per GATE of .001 SECOND WHEN "100" => GATE_CNT_LIMIT <= 50000; -- 50000 a bit of delay, for LED mux disp refresh WHEN OTHERS => NULL; END CASE; END PROCESS; -- TIMER -- This timer is enabled when "ent_ena" signal is asserted. -- Synchronous to the 10MHZ clock, on the rising edge PROCESS (cnt_ena, ref_clk ) BEGIN IF (cnt_ena=LOW) THEN gate_counter <= 0; ELSIF (ref_clk=HIGH and ref_clk'EVENT) THEN gate_counter <= gate_counter + 1; END IF; END PROCESS; -- 100KHz clock generator -- This is a divider which gnerates 100KHz clock from the 10MHz clock in -- The 100KHz clock is used on the LED display segment refreshing PROCESS (sys_rst_l, ref_clk) VARIABLE counter : INTEGER range 0 TO 50; BEGIN IF (sys_rst_l='0') THEN -- active low, asynchronous reset clk_100KHZ <= '0'; counter := 0; ELSIF (ref_clk='1' AND ref_clk'EVENT) THEN -- toggle at 50 ticks of 100nS IF (counter=50) THEN clk_100KHZ <= NOT clk_100KHZ; counter := 0; ELSE counter := counter + 1; END IF; END IF; END PROCESS; END FREQ_COUNTER_RTL;
دیدگاه