Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

n-vector, m-bits long Counter

Status
Not open for further replies.

Jaraqui

Newbie level 5
Joined
May 30, 2011
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,367
Please consider a VHDL module which must behave according to the following scenario (clk = clock input; rst = assynchronous reset):

1) clk, rst --> module --> n-position vector with m-bits
2) n: I need sizes such as 20, ..., 50;
3) m: something like 4 or 8 bits


To reach this I developed the following code for a n-2, m-4 vector

Code:
--...piece of my_package...
type    chr_type is array (1 downto 0) of std_logic_vector(3 downto 0);
type chr_counter is array (1 downto 0) of integer range 0 to 15;


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.my_package.all;
 
entity my_counter_chr is
    port( clk: in std_logic;
          rst: in std_logic;
            q_counter: out chr_type);
end entity;
 
architecture arch of my_counter_chr is
begin   
   process(clk, rst)
       variable counter: chr_counter := (0, 0);
    begin
       if(rst = '1') then
          counter := (0, 0);
        elsif(clk'event and clk = '0') then
          if (counter(0) < 15 and counter(1) < 15) then counter(0) := counter(0) + 1;
            elsif (counter(0) = 15 and counter(1) < 15) then counter(0) := 0; counter (1) := counter(1) + 1;
             elsif (counter(0) < 15 and counter(1) = 15) then counter(0) := counter(0) + 1;
             elsif (counter(0) = 15 and counter(1) = 15) then counter(0) := 0; counter(1) := 0;       
          end if;
        end if;
        q_counter <= (std_logic_vector(to_unsigned(counter(1), 4)) , std_logic_vector(to_unsigned(counter(0), 4)));
    end process;
end arch;



This code works fine, but I think it is a kind of brute force. Generalizing it is pretty ugly.
Any ideias to do this in a clever way will be wellcome.
 

Here is my hint:
Code:
 x        = 100111
~x        = 011000
-x        = 101000
-x xnor x = 001111
-x  and x = 001000
-x nor ~x = 000111

Based on comparisons to terminal counts, you can determine which get incremented and which get reset.

(and if the limit is always (2^n - 1) you can just use a large counter).

--edit: indentation matters.
 
Here is my hint:
Code:
 x        = 100111
~x        = 011000
-x        = 101000
-x xnor x = 001111
-x  and x = 001000
-x nor ~x = 000111

Based on comparisons to terminal counts, you can determine which get incremented and which get reset.

(and if the limit is always (2^n - 1) you can just use a large counter).

--edit: indentation matters.

Thanks for your return!

I didn´t understand your message. Please allow me to do it.

First, I will describe a little more about the code I posted. If you already understood and your comprehension about it is the one bellow, sorry and please disconsider it.

  • The idea behind my little structure is based on the fact that the maximum size of a integer is 32 bits. So, I suppose that a 43, 64, 128, etc, bit counter is infeasible with a simple integer counting -> bit conversion;
  • Based on my supposition, this n-vector was conceived. For instance, if I need a 64/128, etc, bit counting, I can use, respectivelly a n-8, m-8 / n-16, m-8 vector without VHDL integer limit problem;
  • The code I´ve posted is a MWE which counts from 0 to 255 based on triggering the auxiliary chr_counter vector. The sequence of triggering is: (0;0), (0; 1), (0; 2), ..., (0; 14), (0; 15), (1; 0), (1; 1), (1; 2),..., (1; 15), (2; 0), ..., (2; 15), (3; 0), ..., (15; 14), (15; 15); (0; 0), ...
  • The triggering is based on the nested ifs of the code;

Second, regarding your bit-comparison. Is this bits are to be placed in the exit of my integer counting? I 'yes', considering a 128 bit counting, how could it be done, if the integer limit is 32 bit?

Regarding the indentation: is the elsif structure incorrect? Do they have to be placed with indentation or you are reffering to another part of the code?
 

Second, regarding your bit-comparison. Is this bits are to be placed in the exit of my integer counting? I 'yes', considering a 128 bit counting, how could it be done, if the integer limit is 32 bit?
To reiterate what you've said...You are doing all this breaking up a big counter into smaller counters because of a limit on the integer type being 32-bits?

If that is the case, then that is part of your problem. You shouldn't be using an integer type for a counter you should be using the unsigned type, i.e. a type based on SLV that is interpreted as an unsigned number. Similarly to Verilog the integer type is mainly used for things like indexing and for loop variables. It's not used for hardware counters (i.e. synthesized hardware counters). If you do have a need for using as an index (e.g. a memory array address) then you can cast the unsigned to an integer.

Regarding the indentation: is the elsif structure incorrect? Do they have to be placed with indentation or you are reffering to another part of the code?
vGoodtimes was referring to the indented table of x = ???? stuff, they probably posted it originally without the code tags, which the forum automatically removes excess white space at the beginning of a line leaving the table with alignment problems.
 

I wasn't entirely sure what the original problem was, so I gave a hint for an implementation for the general problem. Later I realized that I hadn't indented the code section correctly, so I updated it. That said, it would be nice if more people posted cleanly written code as it makes it easier for a reader to read, understand, and provide feedback.

If everything is a full power-of-two, then you can just use unsigned/signed with addition, and then select the bits you want for each position. unsigned makes the most sense, but the operation is the same either way.

If you have something like watch -- 0-364, 0-23, 0-59, 0-59 where each limit is different, the logic can be implemented by seeing which units are at their terminal counts (364, 23, 59, 59 respectively). This vector can be used with the adder tricks in my post to generate the "add" and "reset" logic. You can also use a for-loop with variables, which might be faster now that I think a bit more about this.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top