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.

8 bit ring counter in VHDL

Status
Not open for further replies.

Jorge Jesse Cantu

Junior Member level 1
Joined
Mar 3, 2014
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
167
I am trying to design an 8-bit self correcting ring counter whose states are 11111110, 11111101,.......,01111111. This includes reset and enable inputs, where the counter goes to the initial state when reset is asserted and counts only if enable input is asserted.

Now I think my code is correct except I am not sure if it's self correcting or not? To make it self correcting what could I implement?

Here is my VHDL code:


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
29
30
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;
 
entity eightRC is 
 
 port(
        CLK : in    std_logic;
        EN: in  std_logic;
        RST : in    std_logic;
        Q: out  std_logic_vector(7 downto 0)
    );
 
end eightRC;
 
architecture behavior of eightRC is
signal qs: std_logic_vector(7 downto 0);
begin
    process(CLK, RST, EN)
    begin 
        if(RST = '1') then
            QS <= "11111110";       --initial state for QS
      elsif (CLK'EVENT AND CLK = '1' and EN = '1') then     --enable starts the shifting
         QS(0) <= QS(7);            --shift '0' to the left each clock edge, Q(0) gets Q(0) bit value
         QS(7 downto 1) <= QS(6 downto 0);
      end if;                      
    Q <= QS;
    end process;
end behavior;

 

I presume the test bench could simply consist on provide initial state conditions for QS not allowable on predicted truth table used for design regular operation of such counter.


+++
 

To make it self correcting you have to start by defining what it is you are correcting for. One flipped bit? Metastability? Hamster invasion?
 
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
Just to give you a hint, don't do one-hot, but use two-hot (if that's a thing).

11111100
11111001
11110011
etc

That way if there is some metastability when you are crossing clock domains you can still get a meaningful result.

The use case? The counter counts on a clock from one clock domain, but the count result is used in another clock domain. Using this kind of ring counter with 2-hot makes it robust against metastability. Even when all the bits that just changed during a count event are metastable, you can still decode a sensible value for the counter. You could do the same sort of thing with a Gray code counter, but this is simpler in many respects.


Mmmh, just thought of something... does anyone know which transition is more or less likely to cause metastability on modern fpga's? 1 => 0, or 0 => 1. That is, if there is a difference in probability at all. If there is, it's probably process dependent too. Reason I ask should be pretty obvious given the subject. ;)
 

A fail safe self-correction logic should not rely on assumptions about expectable illegal states. It should reset the state memory for all possible illegal states. That's what e.g. the "safe encoding" option of the Altera Quartus state machine generator does.

An illegal state doesn't occur without a serious violation of operation conditions, e.g. timing contraints. In so far it's no normal operation. Self-correction logic should be used where a logic design is at risk not to recover otherwise from illegals states.
 

How about using self correcting TMR ;-)
 

Just to be clear. What I wrote was NOT intended for fail safe stuff. If you want your logic to survive ionizing particle bombardment, other measures are required. I gave an example of how to have a counter in 1 clock domain, and then have the synchronized counter in the other domain work without problems, with the count being off by one in a very small number of occurences. I.e when the setup/hold times are violated, by design I might add. :p And yes, that use is rather application specific. Not intended for sync logic.

And in that use the tripple redundancy isn't going to help you any. ;-) The old problem with the man with one clock versus 2 (or 3 in this case XD). Might as well just have the one meta-stable clock (the time piece, not the signal) and roll with it.
 

Although many tips were given concerning the scope, I´m not sure if the initial question was properly answered. which if I understood correctly, he was asking for a method for attest working of the self correcting feature on the code as expected.



+++
 

To make it self correcting you have to start by defining what it is you are correcting for. One flipped bit? Metastability? Hamster invasion?
Metastability. I think self correcting means that I wanted to make it with some sort of combinational logic to ensure that it never goes metastable. Here is a picture describing a 4 bit self correcting counter. I personally was just confused and how to code this within my code:

selfcorrecting.PNGselfcorrecting.PNG
 

In this case with the bit sequence you are using you want to take all the upper bits Q(7 downto 1) and compare it with "1111111" if it isn't then stuff a "1" instead of the Q(7) into Q(0) i.e. Q(0) <= "1' when Q(7 downto 1) /= "1111111"

I'll leave it up to you to figure out how to code this as you still have to deal with the counter when it is correctly cycling (there will be non "1111111" values at that time)

Hint, you need to know there isn't just a single 0 in the full 8-bit vector.
 

In the post #1 example, all vectors that don't contain exactly one '0' are incorrect. There are two possible correction methods:
- the said fail-safe state machine encoding that immediately resets all bits to the initial state after detecting an illegal bit combination
- the sequential self-correction method sketched in post #9 which needs less logic.

Code:
if QS(6 downto 0) = "1111111" then
  QS(0) <= '0';
else 
  QS(0) <= '1';
end if;
QS(7 downto 1) <= QS(6 downto 0);
 

In this case with the bit sequence you are using you want to take all the upper bits Q(7 downto 1) and compare it with "1111111" if it isn't then stuff a "1" instead of the Q(7) into Q(0) i.e. Q(0) <= "1' when Q(7 downto 1) /= "1111111"

I'll leave it up to you to figure out how to code this as you still have to deal with the counter when it is correctly cycling (there will be non "1111111" values at that time)

Hint, you need to know there isn't just a single 0 in the full 8-bit vector.

Would this work?

HTML:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;

entity eightRC is 

 port(
		CLK	: in	std_logic;
		EN: in	std_logic;
		RST : in 	std_logic;
		Q: out	std_logic_vector(7 downto 0)
	);

end eightRC;

architecture behavior of eightRC is
signal q_reg, q_next: std_logic_vector(7 downto 0);
signal e_in : std_logic;
begin
  	process(CLK, RST)
  	begin 
		if(RST = '1') then
			QS <= "11111110";		--initial state for QS
      elsif (CLK'EVENT AND CLK = '1') then	
			  q_reg <= q_next;
			--this is how I was originally doing it, thought I should include for you to see.
         --QS(0) <= QS(7);  			--shift '0' to the left each clock edge, Q(0) gets Q(0) bit value
         --QS(7 downto 1) <= QS(6 downto 0);
      end if;                      
  	end process;
	e_in <= '1' when q_reg(7 downto 1) = "11111111" else '0';
	q_next <= e_in and q_reg(7 downto 1);
	Q <= q_reg;
	EN <= e_in;
end behavior;
 

Would this work?
Not exactly, but something like this. I think, a correct solution is in my previous post.

But rather than believe it, use a testbench.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top