URL
https://opencores.org/ocsvn/astron_counter/astron_counter/trunk
Subversion Repositories astron_counter
Compare Revisions
- This comparison shows the changes necessary to convert path
/astron_counter/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/common_counter.vhd
0,0 → 1,99
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2009 |
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> |
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands |
-- |
-- This program is free software: you can redistribute it and/or modify |
-- it under the terms of the GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- This program is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- GNU General Public License for more details. |
-- |
-- You should have received a copy of the GNU General Public License |
-- along with this program. If not, see <http://www.gnu.org/licenses/>. |
-- |
------------------------------------------------------------------------------- |
|
-- Purpose : Counter with extra options |
-- Description: |
-- - default wrap at 2**g_width or special wrap at fixed g_max or dynamically via cnt_max |
-- - default increment +1 or other g_step_size |
-- - external clr |
-- - external load with g_init or dynamically via load |
-- Remarks: |
-- . If g_max = 2**g_width then use g_max=0 for default wrap and avoid truncation warning. |
-- The check g_max = 2**g_width does not work for g_width >= 31 due to that the INTEGER |
-- range in VHDL is limited to -2**31 to +2**31-1. Therefore detect that g_max = 2**g_width |
-- via ceil_log2(g_max+1)>g_width and use this to init the cnt_max input. |
|
LIBRARY IEEE, common_pkg_lib; |
USE IEEE.std_logic_1164.all; |
USE common_pkg_lib.common_pkg.ALL; |
|
|
ENTITY common_counter IS |
GENERIC ( |
g_latency : NATURAL := 1; -- default 1 for registered count output, use 0 for immediate combinatorial count output |
g_init : INTEGER := 0; |
g_width : NATURAL := 32; |
g_max : NATURAL := 0; -- default 0 to disable the g_max setting. |
g_step_size : INTEGER := 1 -- counting in steps of g_step_size, can be + or - |
); |
PORT ( |
rst : IN STD_LOGIC := '0'; -- either use asynchronous rst or synchronous cnt_clr |
clk : IN STD_LOGIC; |
clken : IN STD_LOGIC := '1'; |
cnt_clr : IN STD_LOGIC := '0'; -- synchronous cnt_clr is only interpreted when clken is active |
cnt_ld : IN STD_LOGIC := '0'; -- cnt_ld loads the output count with the input load value, independent of cnt_en |
cnt_en : IN STD_LOGIC := '1'; |
cnt_max : IN STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_UVEC(sel_a_b(ceil_log2(g_max+1)>g_width, 0, g_max), g_width); -- see remarks |
load : IN STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_SVEC(g_init, g_width); |
count : OUT STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) |
); |
END common_counter; |
|
|
ARCHITECTURE rtl OF common_counter IS |
|
CONSTANT zeros : STD_LOGIC_VECTOR(count'RANGE) := (OTHERS => '0'); -- used to check if cnt_max is zero |
SIGNAL reg_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width); -- in case rst is not used |
SIGNAL nxt_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width); -- to avoid Warning: NUMERIC_STD.">=": metavalue detected, returning FALSE, when using unsigned() |
SIGNAL comb_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width); -- to avoid Warning: NUMERIC_STD.">=": metavalue detected, returning FALSE, when using unsigned() |
|
BEGIN |
|
comb_count <= nxt_count; |
|
count <= comb_count WHEN g_latency=0 ELSE reg_count; |
|
ASSERT g_step_size /= 0 REPORT "common_counter: g_step_size must be /= 0" SEVERITY FAILURE; |
|
p_clk : PROCESS (rst, clk) |
BEGIN |
IF rst = '1' THEN |
reg_count <= TO_SVEC(g_init, g_width); |
ELSIF rising_edge(clk) THEN |
IF clken='1' THEN |
reg_count <= nxt_count; |
END IF; |
END IF; |
END PROCESS; |
|
p_count : PROCESS(reg_count, cnt_clr, cnt_en, cnt_ld, load, cnt_max) |
BEGIN |
nxt_count <= reg_count; |
IF cnt_clr='1' OR (reg_count=cnt_max AND cnt_max /= zeros) THEN |
nxt_count <= (OTHERS => '0'); |
ELSIF cnt_ld='1' THEN |
nxt_count <= load; |
ELSIF cnt_en='1' THEN |
nxt_count <= INCR_UVEC(reg_count, g_step_size); |
END IF; |
END PROCESS; |
|
END rtl; |
/hdllib.cfg
0,0 → 1,19
hdl_lib_name = common_counter |
hdl_library_clause_name = common_counter_lib |
hdl_lib_uses_synth = common_pkg |
hdl_lib_uses_sim = |
hdl_lib_technology = |
|
synth_files = |
common_counter.vhd |
|
test_bench_files = |
tb_common_counter.vhd |
|
regression_test_vhdl = |
|
[modelsim_project_file] |
modelsim_copy_files = |
|
[quartus_project_file] |
|
hdllib.cfg
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tb_common_counter.vhd
===================================================================
--- tb_common_counter.vhd (nonexistent)
+++ tb_common_counter.vhd (revision 2)
@@ -0,0 +1,111 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2011
+-- ASTRON (Netherlands Institute for Radio Astronomy)
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see .
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_pkg_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_pkg_lib.common_pkg.ALL;
+
+ENTITY tb_common_counter IS
+END tb_common_counter;
+
+ARCHITECTURE tb OF tb_common_counter IS
+
+ CONSTANT clk_period : TIME := 10 ns;
+
+ CONSTANT c_cnt_init : NATURAL := 3;
+ CONSTANT c_cnt_w : NATURAL := 5;
+
+ SIGNAL rst : STD_LOGIC;
+ SIGNAL clk : STD_LOGIC := '0';
+
+ SIGNAL cnt_clr : STD_LOGIC := '0'; -- synchronous cnt_clr is only interpreted when clken is active
+ SIGNAL cnt_ld : STD_LOGIC := '0'; -- cnt_ld loads the output count with the input load value, independent of cnt_en
+ SIGNAL cnt_en : STD_LOGIC := '1';
+ SIGNAL load : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0) := TO_UVEC(c_cnt_init, c_cnt_w);
+ SIGNAL count : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0);
+ SIGNAL cnt_max : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0);
+
+BEGIN
+
+ clk <= NOT clk AFTER clk_period/2;
+ rst <= '1', '0' AFTER clk_period*3;
+
+ -- run 1 us
+ p_in_stimuli : PROCESS
+ BEGIN
+ cnt_clr <= '0';
+ cnt_ld <= '0';
+ cnt_en <= '0';
+ cnt_max <= (OTHERS => '0');
+ WAIT UNTIL rst = '0';
+ WAIT UNTIL rising_edge(clk);
+
+ -- Start counting
+ cnt_en <= '1';
+ FOR I IN 0 TO 9 LOOP
+ WAIT UNTIL rising_edge(clk);
+ END LOOP;
+
+ -- Reload counter
+ cnt_ld <= '1';
+ WAIT UNTIL rising_edge(clk);
+ cnt_ld <= '0';
+ FOR I IN 0 TO 9 LOOP
+ WAIT UNTIL rising_edge(clk);
+ END LOOP;
+
+ -- briefly stop counting
+ cnt_en <= '0';
+ WAIT UNTIL rising_edge(clk);
+ -- countine counting
+ cnt_en <= '1';
+ FOR I IN 0 TO 9 LOOP
+ WAIT UNTIL rising_edge(clk);
+ END LOOP;
+
+ -- set the cnt_max
+ cnt_max <= TO_UVEC(2**(c_cnt_w-1), c_cnt_w);
+
+ WAIT;
+ END PROCESS;
+
+ -- device under test
+ u_dut : ENTITY work.common_counter
+ GENERIC MAP (
+ g_init => c_cnt_init,
+ g_width => c_cnt_w,
+ g_step_size => 1
+ )
+ PORT MAP (
+ rst => rst,
+ clk => clk,
+ cnt_clr => cnt_clr,
+ cnt_ld => cnt_ld,
+ cnt_en => cnt_en,
+ cnt_max => cnt_max,
+ load => load,
+ count => count
+ );
+
+END tb;
+
+
tb_common_counter.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property