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.

comparator with a single input

Status
Not open for further replies.

kcinimod

Member level 3
Joined
Dec 19, 2011
Messages
63
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,714
how should i program a comparator with just one input (random numbers), that compares the first and second number, then compares the third and fourth number and so on. And outputs a '1' or '0' if greater or less than respectively and nothing if the 2 numbers are equal ? Appreciate the help.
 

just register the input and compare the registered version to the input. Also have a signal to tell you when the input is even, so you know to ignore every other result (otherwise you will compare 1 > 2, 2 > 3, 3 > 4 etc).
 

do you mind giving me a sample code ? i rather new at VHDL and i'm unsure of the syntax
 
No, because I am assuming this is an assignment you are supposed to do. So I shall leave the bulk of it to you (go and learn VHDL from a tutorial)

But in VHDL for a comparator you can simply write:

Code:
if a > b then
  output <= '1';
else
  output <= '0';
end if;
 

thx, btw do you know what this warning means ?

Pruning bit 8 of pre_count_1(31 downto 0) - not in use ...
 

it means bit 8 is stuck at '0' or '1'.

any chance you can post the code.

---------- Post added at 11:22 ---------- Previous post was at 11:21 ----------

btw - I suggest you try simulating your design before synthesising it.
 

library ieee;
use ieee.std_logic_1164.all;


entity counter is
port(
clk : in std_logic;
data : in std_logic;
enable : in std_logic;
count : out integer

);
end counter;

architecture count of counter is


begin
process (clk, data, enable)
variable pre_count : integer ;
begin
if (data = '1') then
pre_count := 0;
elsif (clk'EVENT AND clk = '1') then
if enable = '1' then
pre_count := pre_count + 1;
else
pre_count := pre_count;
end if;
end if;
count <= pre_count;
end process;



end count;

this is my code for a simple counter and i got this warnings,

WARNING - ngdbuild: logical net 'pre_count_cry_0' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_2' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_4' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_6' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_8' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_10' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_12' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_14' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_16' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_18' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_20' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_22' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_24' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_26' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_28' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_30' has no load
WARNING - ngdbuild: logical net 'pre_count_cry_0_COUT1_30' has no load
 

ok. Not a bad first attempt. I would highly suggest you stay away from variables for now - they have a behaviour that may cause you problems (and it may be causing you problems here).

Make pre_count a signal inside the entity, and work it like this:

Code:
architecture count of counter is
  signal pre_count : integer;

begin
  
  process (clk, data)   --dont need to put enable in here, because you dont change anything when enable changes (you need a clock for things to change)
  begin
    if (data = '1') then  --are you sure you want data as your async reset?
      pre_count <= 0;
    elsif (clk'EVENT AND clk = '1') then
      if enable = '1' then
        pre_count <= pre_count + 1;
      
      --no need for an else here because it's registered and so holds its value implicitly
      end if;
    end if;
      
    
  end process;

  --outside the process
  count <= pre_count;

end count;

You do realise that count is a 32 bit signed value? Also, In simulation, when it gets to 2^31-1 it will NOT roll over - you will get an overflow error, but on real hardware it will overflow. You may want to look at the signed/unsigned types from the numeric_std package, as you will get the same behaviour in simulation and hardware, and you can also set the width of the count value (from 1 bit to however big you want)
 
for my assigned system, i need to count the number of clock cycles when a pulse is detected to the next pulse ( pulse are generated randomly), therefore i used data (pulse ) as the reset.
i initially used variable as i need to store the count somewhere as i need to compare the count of the 1st pulse and that of the 2nd pulse, then compare that of 3rd pulse and 4th pulse and so on. can i do that using signal ?
 

yes, signals store values and it might be best for you to think of them as variables for now. There are some subtle difference between signals and variables - variables are assigned immediatly, whereas signals are updated the next time the process they are assigned in suspends, and they take the last assignment given to them.

for example:
Code:
signal a : integer;

process(clk)
  variable b : integer;
begin
  if reset = '1' then
    a <= 0;
    b <= 0;
    
  if rising_edge(clk) then
    
    --variables
    op0 <= b;
    b := b + 1;
    
    op1 <= b;
    b := b + 1;
    
    op2 <= b;
    b := b + 1;
    
    --signals
    op3 <= a;
    a <= a + 1;
    
    op4 <= a;
    a <= a + 1;
    
    op5 <= a;
    a <= a + 1;    
    
  end if;
end process;

In this code, lets assume a and b have just been reset to 0. Now on the first clock cycle, b, being a variable is updated 3 times. but a is only updated once. So the outputs would be:

op0 = 0
op1 = 1
op2 = 2
on the next clock, b starts at 3, so the outputs will 3 4 and 5.

op3 = 0
op4 = 0
op5 = 0
on the next clock, a is 1, so all the ops will be 1

This is because b is updated immediatly every time its assigned, and so all the outputs are different (think of it as the output of a 3 separate adders, after register)
The signal a is updated when the process suspends and is only assigned the last thing given to it - a <= a + 1. (think of a as the output of a register, with the adder before the register)

Variables are more sensitive to code order whereas signals are not. In terms of hardware, its easier to use signals to get the behaviour you expect.


For your code, I suggest you draw your circuit before writing the VHDL. Thinking of the circuit - if Data is asynchronous to the clock - I HIGHLY suggest you synchronise it first (double register) to stop any meta stability and timing issues when you reset things. So it will become an sync reset. Getting into to good habits now will help you alot in future.
 
if i assign a value say 1 using (signal count_1 : integer <= 1) to a signal before the process, and this signal is changed to 2 (count_1 <= 2) within a process, the next time the process runs, will the signal be of value 1 or 2 ?
 

Im not sure exactly what you mean - please write the code for it (and use the forum code tags rather than writing it direct in a post)
 

with regards to the counter, i would like to modify it such that is has now 2 outputs with each reset, the output will be alternating between the 2 output.
not sure if the following codes will work.

Code:
library ieee;
use ieee.std_logic_1164.all;
	

entity counter is
	port( 
		clk  : in std_logic;
		data : in std_logic;
		enable  : in std_logic;
	    count_one : out integer; 
		count_two : out integer
	);
end counter;

architecture count of counter is
	signal pre_count : integer;
	signal x : integer :=1 ;	
	
begin
	process (clk, data)
	begin
		if (data = '1') then
			pre_count <= 0;
		elsif (clk'EVENT AND clk = '1') then
			if enable = '1' then
				pre_count <= pre_count + 1;
			end if;
		end if;
	end process;
	
	process (data)
	begin
		if (data ='1') then
			if (x = 1) then
				count_one <= pre_count;
				x := 2;
			elsif (x=2) then
				count_two <= pre_count;
				x :=1;
			end if;
		end if;
	end process;
			
end count;
 

the problem with the second process is that it is an asynchronous process, and the way you have got it you are going to create latches. I suggest you use the clock, and not data to do the data logging.

Some suggestions.
- Make x a std_logic rather than an integer. You dont need a 32 bit number to toggle 1 bit.
- Synchronise the second process.

Code:
signal x : std_logic := '0';

process (clk)
begin
  if rising_edge(clk) then
	  
    x <= not x;
	  
    if x = '0' then
      count_one <= pre_count;
			
    else
      count_two <= pre_count;
			
    end if;
  end if;
end process;

So the count_one and count_two values will store the value of the pre_count on alternate counts. Yes it has an extra clock cycle of latency, but this is what pipelining does.
 
if i use the clock, the alternating count will be of every single clock cycle, if i have interpreted your codes correctly. however, i would like the count to be the total count after each reset, and to alternate this total count between the 2 outputs so should i use the data instead ?
 

you will need to register the count value on the falling edge of the synchronised data signal.
 

meaning the sensitivity list for the second process will have to be (data) ?
 

no. Im not talking about code.
A synchronised data signal will be a double registered version of data to avoid meta-stability, assuming its completly asynchronous to the clock (if its synchronous to the clock, then there is no problem.)

You need to do something like this:

Code:
signal data_sync : std_logic_vector(1 downto 0);

process(clk)
begin
  if rising_edge(clk) then
    data_sync <= data_sync(0) & data;
  end if;
end process;


count_proc : processs(clk)
begin
  if rising_edge(clk) then
    if data_sync(1) = '1' then
      count <= count + 1;
    end if;
  end if;
end process;

Making a process sensitive to data just means you're creating logic sensitive to the data signal (probably without registers). The above code synchronises the data signal and then uses that to measure the time its high for.
 

if you have multiple processes within an architecture, will the processes be carried out in the order you have written it or it will do concurrently as long as signals in the sensitivity list changes ?
i have also picked up this code on the web, are they similar to what you have written ?

Code:
library ieee;
use ieee.std_logic_1164.all ;

entity delta is
   port (clk    : in  std_logic;
         din    : in  std_logic;
         dout  : out std_logic); 
end delta;
 
architecture rtl of delta is

signal q_s     : std_logic:='0';
signal clk_s   : std_logic;

begin
   process (clk)
    begin
        if rising_edge(clk) then  
            q_s <= din;
        end if ;
    end process ;
 
    clk_s <= clk;  -- delta delay!
 
   process (clk_s)
     begin
        if rising_edge(clk_s) then  
            dout <= q_s;
        end if ;
    end process ;
end rtl;
 
Last edited:

That code is a demonstration of how VHDL works. In simulation, it will show a 1 clock delay between the input and output, but on real hardware it will be 2 clocks. So please ignore this code for now.

In VHDL, all processes always run concurrently. You can have as many processes as you want. Each process is executed when any of the signals in the sensitivity list has a 'event (a change). We only put the clock in the sensitivity list because we only want things to change on the clock edges, but we have to make sure we specify that with the "if rising_edge(clk) then" bit.

It sounds like you have a software background. I highly suggest you forget about programming, forget about VHDL for now and try drawing your intended circuits on a bit of paper. VHDL is not a programming language, it is a description language (VHDL = VHSIC Hardware Description Language). If you have no idea what circuit you are describing, you have no chance in writing useful code.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top