Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21611 Discussions

How to find largest value and its position in memory array?

Altera_Forum
Honored Contributor II
13,198 Views

As attachment... the memory array contains continuous input at every positive edge clock... these inputs are the outputs from the Altera FFT core... then i need to find the peak and its location... please help!!! thanks alot! from the attachment, the peak should be 45 and at memory_array [2].... and they should be shown at the outputs...

0 Kudos
26 Replies
Altera_Forum
Honored Contributor II
9,268 Views

to get max of stream: 

in a clocked process: 

if din > max then 

max <= din; 

addr_of_max <= addr; 

end if;
0 Kudos
Altera_Forum
Honored Contributor II
9,267 Views

 

--- Quote Start ---  

to get max of stream: 

in a clocked process: 

if din > max then 

max <= din; 

addr_of_max <= addr; 

end if; 

--- Quote End ---  

 

 

Hi Kaz, thanks for your reply... i know the concept... but I have no idea how to write it in Verilog code... though I have tried for several times, the output is wrong...
0 Kudos
Altera_Forum
Honored Contributor II
9,267 Views

I have written the code in vhdl, which should work provided you look after type issues(signed...etc). 

You can write verilog on same basis.
0 Kudos
Altera_Forum
Honored Contributor II
9,267 Views

 

--- Quote Start ---  

I have written the code in vhdl, which should work provided you look after type issues(signed...etc). 

You can write verilog on same basis. 

--- Quote End ---  

 

 

Hi Kaz, here is my code... but it's wrong... can you figure out my mistake? 

 

 

module absolute(clock,Enable, d_in, max_value) ;  

 

input wire clock;  

input wire Enable;  

input wire [9:0] d_in; 

output reg [9:0] max_value; 

 

reg [9:0] max_val_tmp; 

reg [2:0] Q; 

reg [9:0] mem_array [0:7]; 

 

initial 

begin 

max_val_tmp = mem_array[0]; 

end 

 

 

always @ (posedge clock) 

begin  

if (Enable)  

begin 

mem_array[Q] <= d_in; 

if (mem_array[Q] > max_val_tmp) 

begin 

max_value <= mem_array[Q]; 

end 

else 

begin  

max_value <= max_val_tmp; 

end 

Q <= Q + 1; 

 

end 

end 

 

endmodule
0 Kudos
Altera_Forum
Honored Contributor II
9,267 Views

I suggested: 

 

always @ (posedge clock) begin if (Enable) begin if (din > max_val) begin max_val <= din; Q_val <= Q; end Q <= Q + 1; end end  

 

you need to take care of verilog syntax and rules as I am not good at it. You also need to take care of address latency. 

I also thought you are reading from memory but your code suggest are just writing to an array from din?? so which is'it? Anyway the code for din above should work in principle. what you do with din before/after is your focus.
0 Kudos
Altera_Forum
Honored Contributor II
9,269 Views

 

--- Quote Start ---  

I suggested: 

 

always @ (posedge clock) begin if (Enable) begin if (din > max_val) begin max_val <= din; Q_val <= Q; end Q <= Q + 1; end end  

 

you need to take care of verilog syntax and rules as I am not good at it. You also need to take care of address latency. 

I also thought you are reading from memory but your code suggest are just writing to an array from din?? so which is'it? Anyway the code for din above should work in principle. what you do with din before/after is your focus. 

--- Quote End ---  

 

 

Thank you Kaz for your time :) 

 

I have tried the codes below, both with mem_array and without mem_array gave the same results which are wrong... (as picture attachment) 

 

module absolute(clock,Enable, d_in, max_value, max_location) ;  

 

input wire clock;  

input wire Enable;  

input wire [9:0] d_in; 

output reg [9:0] max_value; 

output reg [2:0] max_location; 

 

reg [9:0] max_val_tmp; 

reg [2:0] Q; 

//reg [9:0] mem_array [0:7]; 

 

initial 

begin 

max_val_tmp = 0; 

end 

 

 

always @ (posedge clock) 

begin  

if (Enable)  

begin 

//mem_array[Q] <= d_in; 

if (d_in > max_val_tmp) 

begin 

max_value <= d_in; 

max_location <= Q; 

end 

Q <= Q + 1; 

end  

end 

 

endmodule 

 

 

**p.s. I need to write d_in into mem_array[Q] so that i can keep track on its location right? 

**another way i found something: 

"develop a verilog model for a peak detector that finds the maximum value in a sequence of 10-bit unsigned integers. a new number arrives at the input during a clock cycle when the data_en input is 1. if the new number is greater than the previously stored maximum value, the maximum value is updated with the new number; otherwise, it is unchanged. the stored maximum value is cleared to zero when the reset control input is 1. both data_en and reset are synchronous control inputs."
0 Kudos
Altera_Forum
Honored Contributor II
9,269 Views

 

--- Quote Start ---  

Thank you Kaz for your time :) 

**p.s. I need to write d_in into mem_array[Q] so that i can keep track on its location right? 

**another way i found something: 

"develop a verilog model for a peak detector that finds the maximum value in a sequence of 10-bit unsigned integers. a new number arrives at the input during a clock cycle when the data_en input is 1. if the new number is greater than the previously stored maximum value, the maximum value is updated with the new number; otherwise, it is unchanged. the stored maximum value is cleared to zero when the reset control input is 1. both data_en and reset are synchronous control inputs.

--- Quote End ---  

 

 

What another way? It is same one I am telling you since last year!! 

 

and your code : why do you keep using the wrong signal name: why do you use max_val_tmp, I did not say that.
0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

 

--- Quote Start ---  

What another way? It is same one I am telling you since last year!! 

 

and your code : why do you keep using the wrong signal name: why do you use max_val_tmp, I did not say that. 

--- Quote End ---  

 

 

last year?? i just joined today... if i didn't create a temparory reg "max_val_tmp" how can keep the number for comparing with the next number?? 

 

if you don't mind to edit my whole codes, so i don't make any mistakes again won't ask you anymore??
0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

now i change to these codes and the output as shown in picture attachment...  

 

input wire Enable;  

input wire [9:0] d_in; 

output reg [9:0] max_value; 

output reg [2:0] max_location; 

 

 

reg [2:0] Q; 

 

 

initial 

begin 

max_value = 0; 

end 

 

 

always @ (posedge clock) 

begin  

if (Enable)  

begin 

 

if (d_in > max_value) 

begin 

max_value <= d_in; 

max_location <= Q; 

end 

Q <= Q + 1; 

end  

end 

 

endmodule
0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

Just use my above code. The max_val updates and stores din by itself until it is updated (if at all). 

I am sorry I have not done verilog for years so can't help directly at code level. 

 

Yourlast code and waveforms looks ok to me
0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

 

--- Quote Start ---  

Just use my above code. The max_val updates and stores din by itself until it is updated (if at all). 

I am sorry I have not done verilog for years so can't help directly at code level. 

 

Yourlast code and waveforms looks ok to me 

--- Quote End ---  

 

 

Ya the last code is ok i think... but is it posibble to output only the max_value "256" and location "6" throughout the waveforms?
0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

once value 256 comes in it will displace any lower value at max_val and will stay so until a higher value comes in and kicks it out

0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

okok... i understood this... but i need the waveform show only the largest value without showing the previous smaller values... never mind, i try to find solution myself... thanks so much anyway :)

0 Kudos
Altera_Forum
Honored Contributor II
9,268 Views

 

--- Quote Start ---  

okok... i understood this... but i need the waveform show only the largest value without showing the previous smaller values... never mind, i try to find solution myself... thanks so much anyway :) 

--- Quote End ---  

 

 

The waveform displays values of the node(max_val) so you will always see its values from time zero.  

you can add further node saying if val = 255 then max_final = 255  

but I haven't got a clue what use this is going to be.
0 Kudos
Altera_Forum
Honored Contributor II
9,269 Views

Hi Kaz... i have another question to ask... as attached picture.... if i have the data_in like that, started at a "later" positive edge clock, i want it to be outputted at the first positive edge clock as shown in d_out, do you know how to do that?

0 Kudos
Altera_Forum
Honored Contributor II
9,270 Views

haven't you already done that as evident from your sim waveforms. 

You will need a time machine to do that (internal delays)
0 Kudos
Altera_Forum
Honored Contributor II
9,270 Views

 

--- Quote Start ---  

haven't you already done that as evident from your sim waveforms. 

You will need a time machine to do that (internal delays) 

--- Quote End ---  

 

 

No i didn't simulate it... that one i drew... i know how to do delay(move the d_in backwards), but don't know how to move it forward... cos now if the input is shown as the previous attachment.... i want to start counting the peak from '15'... not from '0'... 

 

mem_array[Q] <= d_in; 

d_out <= mem_array[Q-3]; //these codes are for delay...
0 Kudos
Altera_Forum
Honored Contributor II
9,270 Views

If I can move data forward I wouldn't be here as I will just win lotteries

0 Kudos
Altera_Forum
Honored Contributor II
9,270 Views

ok... cos now after passing through the FFT core, the output of FFT is like the d_in i showed... i want to find the peak value and its location... yes the peak value can be found but the location shown is not correct as it's not counted from the first valid output of the FFT core... and also i want to find several peaks to find what frequencies have been inputted... if you don't know how to do it, then never mind... thanks for your replies...

0 Kudos
Altera_Forum
Honored Contributor II
8,286 Views

 

--- Quote Start ---  

ok... cos now after passing through the FFT core, the output of FFT is like the d_in i showed... i want to find the peak value and its location... yes the peak value can be found but the location shown is not correct as it's not counted from the first valid output of the FFT core... and also i want to find several peaks to find what frequencies have been inputted... if you don't know how to do it, then never mind... thanks for your replies... 

--- Quote End ---  

 

 

you don't need to push fft output forward. All you need is check the fft frame when ready for peaks. The location of peak need to be adjusted for latency issues so you need to check that in simulation.  

For multiple peaks you shouldn't use max value, instead you need to define an absolute threshold to define your peaks then check fft output against that threshold, save peaks accordingly.
0 Kudos
Reply