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.

Nested clock in vhdl

Status
Not open for further replies.

ananthan95

Junior Member level 3
Joined
Oct 19, 2017
Messages
31
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
289
hey, I am a beginner in VHDL programming. I have an issue now please help.
I have two arrays of numbers(15nos of integer type). the ultimate goal is to multiply the numbers individually in these arrays. but the condition is the multiplication should start with respect to one clock and proceed according to a second clock. how do i do that? i use vivado2017.2 and it says nesting is impossible
 

Re: nested clock in vhdl

Hi,

It´s not clear to me what you mean.
I assume you need some type of pipelining - usually this is made with DFF.

Klaus
 
Re: nested clock in vhdl

thank u for replying. lets say
sine := (7,4,2,0,0,1,3,6,9,11,13,14,14,12,10,7,0);
sine2 := (0,0,1,3,6,9,11,13,14,14,12,10,7,0,7,4,2);
these are my arrays. i want the multiplication to happen in such a way that 7*0, 4*0, 2*1, 0*3 etc.. till 0*2
the issue is the multiplication should start withrespect to one clock signal ( say clk1) and from then proceed according to
an another clock (clk 2)!!
 

Re: nested clock in vhdl

Hi,

OK.
Let´s call "clk1" --> "trigger"

"Trigger" resets a counter for a state machine.
* with each clk2 it increments the counter
* according counter value it takes a pair of input data and multiplies them.
* after all is done it raises a "finished" signal and stops counting

Klaus
 
Re: nested clock in vhdl

Why not post some code, so we get an idea of what you're trying to do?
You cant use 2 clocks on a single register in an FPGA. But I dont understand why you'd want to use 2...
 

Re: nested clock in vhdl

it actually worked. thanks to @klausST
I am actually working on phase matching of two sine waves.it includes a zero crossing detector and some further manipulations on the waves.
 

Re: nested clock in vhdl

the issue is the multiplication should start withrespect to one clock signal ( say clk1) and from then proceed according to an another clock (clk 2)!!

Are you sure you have understood the requirement correctly?
Is it another clock clk2 or the 2nd rising edge of the first clock clk1?
 

Re: nested clock in vhdl

yea I needed two clock signals. I will post my code below if you have an alternative idea pls comment. as I mentioned in the above comment, this s a part of phase matching two sine waves.

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;

entity zcd01 is
    Port ( clk : in std_logic;
           d : out integer;
           d1 : out integer;
           op1 : inout STD_LOGIC;
           res : out integer);
end zcd01;

architecture Behavioral of zcd01 is
type sine is array (0 to 16) of integer;
type sine2 is array (0 to 16) of integer;
signal val0 : sine := (7,4,2,0,0,1,3,6,9,11,13,14,14,12,10,7,0);
signal val : sine2 := (0,0,1,3,6,9,11,13,14,14,12,10,7,0,7,4,2);
signal c:integer:=0;
signal ptr : integer;

begin

process (clk)
constant ref :integer :=7;
begin
if rising_edge(clk) then
   d <= val0(c);
   d1 <= val(c);
      if val (c) = ref then op1 <= '1';
       else if (ref - val(c))<0 and (ref - val (c-1)) > 0 then op1 <= '1';
       else op1 <= '0';
       end if;
      end if;  
 c <= c+1;
 end if;
 end process;     
 
process (op1,clk)
begin 
 if op1' event and op1 = '1' then
    ptr <= 0;
 end if;
 if rising_edge(clk) then   
    if ptr >= 0 then res <= val0(c) * val (c);
    end if;
    ptr <= ptr +1;
  end if;   
end process;     
end Behavioral;
 

Re: nested clock in vhdl

Basically, you cant have a register with 1 clocks on an FPGA.
But why cant OP1 be a synchronous reset with a single clock wide pulse? Or do an edge detect on op1?


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
signal op1_r : std_logic;
 
process(clk)
begin
  if rising_edge(clk) then
    op1_r   <= op1;
    
    if ptr >= 0 then res <= val0(c) * val (c);
    end if;
 
    ptr <= ptr +1;
 
    if op1 = '1' and op1_r = '0' then  -- rising_edge detection of op1 - reset ptr.
      ptr <= 0;
    end if;
  end if;
end process;



- - - Updated - - -

Btw, this is pretty redundant, as ptr is always >= 0:

if ptr >= 0 then res <= val0(c) * val (c);

Also, your code will fail in simulation when C reaches 18, as it will overflow the Val and val0 arrays. Also, as the arrays are not 2**n in size, unless you have some overflow protection logic, it will create an array of 2**n and likely fill them with 0s.
 
ya, I got ur point. thank you for the code. but then how do I keep the code running even after c reaches 18? I need a cyclic process
 

ya, I got ur point. thank you for the code. but then how do I keep the code running even after c reaches 18? I need a cyclic process

Your code always "runs" in hardware. It is a circuit you are designing, not a software program. Therefore it never ends.
You need some way to reset C. maybe set it back to 0 after it reaches 17?
 
Hi,

in post #4 I wrote "and stops counting".

but for sure you may
* multiply with counter values of 0..17 and stop at 18 (idle state) , (and trigger with clearing the counter value to 0) or
* stop with 0 (idle state); multiply with counter values of 1..18, and after 18 --> clear counter value to 0, (and trigger with setting counter value to 1)
it´s almost the same.

Klaus
 

yea thank you. I added a conditional statement to reset c. it is working.i am adding the simulated output image
cyclic_pm00.JPG
 

Hi,

Looks good. ;-)

Usually it makes no sense to (re-) trigger the multiplication sequence as long as it is in progress, therefore the recommendation to generate a signal when the multiplication is finished / idle.
For sure you may automatically inhibit the retrigger as long as the sequecne is running...to ensure a full run over all items.

BTW: you call the arrays "sine" but indeed it not seems to be a sinewave.

Klaus
 
yea. it is a sine wave. i used a floor function in matlab to get thse values. now following the earlier code, that was a simle attempt of mine to understand the code. now i have an issue. i will paste my actual code now.
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;
use IEEE.NUMERIC_STD.ALL;

entity scheme_demod is
    Port (-- TX_DATA : in  signed (16 downto 0);
          --RX_DATA : in  signed (16 downto 0);
           --clk : in  STD_LOGIC;
           demod_clk : in  STD_LOGIC;
 --          rx_data_compl : in  STD_LOGIC;   
           --tx_data_compl : in  STD_LOGIC;  -- will be high if all data values are send
           b_count : out  STD_LOGIC; -- to uart for completion  and start of byte ( b_count =1 complete, b_count= 0 start) 
           start_data : out  STD_LOGIC; --- to spiTX and spiRX ( if 0 means start sensding the data from tX)
			  start_data1 : out STD_LOGIC;
           DATA_OUT : out  std_logic_vector (39 downto 0);
           op : inout std_logic :='0';
           sin : inout signed(16 downto 0);
           sin1 : inout signed(16 downto 0);
           sin2 : inout signed(16 downto 0));
          
           --temp_sum :inout integer);
end scheme_demod;

architecture Behavioral of scheme_demod is

 type bus_type is array(0 to 23) of integer range 0 to 65535;
 signal TX_DATA : bus_type :=(32767,40609,47995,54496,59735,63406,65296,63406,59735,54496,47995,40609,32767,24924,17538,11037,5798,2129,238,2129,5798,11037,17538,24924);
 signal RX_DATA : bus_type :=(54496,59735,63406,65296,63406,59735,54496,47995,40609,32767,24924,17538,11037,5798,2129,238,2129,5798,11037,17538,24924,32767,40609,47995);
 signal temp_sum : signed(39 downto 0) :="0000000000000000000000000000000000000000";
 signal test : std_logic := '1';  
 signal test1 : std_logic := '1';
 signal ptr: integer; 
 --signal sum :signed (39 downto 0):="0000000000000000000000000000000000000000";
 type bus_type1 is array (0 to 23) of signed (16 downto 0);
 signal temp_tx : bus_type1 :=(others =>(others => '0'));
 signal temp_rx : bus_type1 :=(others =>(others => '0'));
 signal temp : signed(39 downto 0) :="0000000000000000000000000000000000000000";
 type bus_type2 is array (0 to 23) of signed (16 downto 0);
 signal new_rx : bus_type2 :=(others =>(others => '0'));

 --signal int : integer;

begin
start_data <= test ; --or test1; --- changed on 30/03/2016 from "test" to " or test1"
start_data1 <= test1;
process (demod_clk)
	variable i : integer :=0;
	variable a: integer :=0;
	variable b : integer;

 begin
	if rising_edge(demod_clk)then
				b_count <= '0';
				temp_tx(i) <=to_signed( TX_DATA(i) - 32767,17);
				temp_rx(i) <=to_signed( RX_DATA(i) - 32767,17);
                 if (0 - temp_rx(i)) > 0 and (0 - temp_rx(i+1)) = 0 then
                    op <= '1';
                    ptr <= i;
                   else 
                       op <= '0';
                   end if;
                i := i + 1;
    end if;       
	            if (i = 24) then
		        test <= '0';
	          	i := 0;
	            end if;
	--end if;
end process;

process(op,demod_clk)
variable j1: integer;
variable k,p : integer :=0;
variable p1 : std_logic := '0';
begin
    if op' event and op = '1' then
       p1 := '1';
       j1 :=ptr+1;
       end if;
      
    if rising_edge(demod_clk) then    
                if p1 = '1' then 
                  new_rx(p) <= temp_rx(j1);	

                   sin <= temp_tx(p);
                   sin1 <= new_rx(p);
                   sin2 <= temp_rx(p);
                   temp_sum <= temp_sum + (temp_tx(k) * new_rx(k));
		           j1 := j1+1;
		           p := p+1;
		           k := k+1; 
		           if (j1 = 24)then j1 :=0;end if;
		        end if;

	end if;	        
	
	           if (k = 24) then
	              temp <= temp_sum + (temp_tx(k-1) * new_rx(k-1)) ; 
	              DATA_OUT <= std_logic_vector(temp);
	              temp_sum <= "0000000000000000000000000000000000000000";
	              k := 0;
	              p := 0;
	              b_count <= '1';
                  test <= '1';  ---added on 30/03/2016 from "test" to " or test1"
                  end if;
		          
              
end process;

end Behavioral;

so basically what i am trying to do is to phase match the missaligned Rx wave with respect to the Tx wave using a zero crossing detector and then multiply the new phase matched Rx wave with TX multiply and sum it over a period(here the period is 24 bcs i am taking 24 data points). the issue i am facing is with the summing part. it is summing only 23 points not 24. when the sum reaches 23, it goes to zero. any solutions??
i ll add my current output as well
ind_sensor07_02.JPG

so at 23rd bit, my sum term is going zero. however i change the counter, it is not giving me the correct output but one less.
 

Likely because you are using variables everywhere, the k variable gets to 24 and immediately evaluated into the term that resets the sum.
 

so you think changing the variable will do the trick? i actually tried it once. i will try again
 

so you think changing the variable will do the trick? i actually tried it once. i will try again

Your best bet, as a beginner, is to not use variables at all. There is nothing you can do with a variable you cannot do with a signal. And signals map more obviously to hardware.
So I suggest making all the variables signals and see where you get.

Otherwise this is a basic debugging exercise - you add everything to the waveform and see if everything functions as intended - find the bug and fix the code. Something you need to do yourself.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top