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.

a program to output a specified image to a stream of integers for VHDL file input

Status
Not open for further replies.
it sounds like you dont quite know whats going on.
With A B and C being images, I still dont know what you're doing. The returned value will be another image D. Usually, the co-effiencient you're talking about are used in the convolution of the input, so:

Output = (Co-eff Maxtrix) x (Small part of input image.)

To do an entire convolution (ie. to get the output) you need to run the co-eff matrix over the entire image. You cannot do this with an even sized co-efficient matrix (2x2, 4x4 etc) otherwise you introduce a 0.5 pixel shift in the output. You then have to consider what you do at the edges when the co-eff matrix spills over the edge (do you zero pad or do you spread the source image?)

So, lets go back to the start. What is your origional algorithm? Do you have it defined in matlab or simulink?
 

Hi TrickyDicky,

A,B and C is not being images. But A,B and C is a signal that will get a value from the input vector (row of matrix). My original algorithm is ((A+B)/2) and B-C (Haar algorithm). I attach the example of calculation of Haar algorithm. I have design the architecture based on this algorithm calculation. Hope you can get what I am try to explain. Thank for reply..
 

Attachments

  • Haar Wavelet Transform.doc
    390.5 KB · Views: 35

This document is not very clear.
The two equations presented do not match up well to the steps taken. But lets take the steps as the approach you should take!

Looking at the steps, you have taken completly the wrong approach to the hardware design.
The best way to process this is to imagine that the pixels arrive 1 at a time. From there you have to control your pipeline to monitor which position the input is at. Then you can enable each step as and when required. Use a data valid signal or clock enable to help control the data.

You can do this without any array inputs Anywhere! you only ever need to input 1 pixel and output 1 value at a time.
 

Hi TrickyDicky,

"The best way to process this is to imagine that the pixels arrive 1 at a time. From there you have to control your pipeline to monitor which position the input is at. Then you can enable each step as and when required. Use a data valid signal or clock enable to help control the data."

Can you give simple example of vhdl code about this matter? I really need your guide and helps. Thank for reply..
 

This code will do a divide by 2 of two adjacent values

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

library floatfixlib;
use floatfixlib.fixed_pkg.all;

entity moving_average is --does divide by 2 on every pair of pixels
  generic (
    IN_HIGH         : integer;
    IN_LOW          : integer
  );
  port (
  
  --clock and reset
  clk               : in  std_logic;
  reset             : in  std_logic;
  
  --input values
  source_pixel        : in  sfixed(IN_HIGH downto IN_LOW);
  source_pixel_valid  : in  std_logic;
  
  --Output
  av_out            : out sfixed(IN_HIGH downto IN_LOW-1); --add extra fraction bit
  av_out_valid      : out std_logic
  );
  
end entity moving_average;
  
architecture rtl of moving_average is
  signal have_two_ips    : std_logic;
  signal ip_r            : sfixed(source_pixel'range);
begin
  
  process(clk, reset)
    variable add_temp    : sfixed(IN_HIGH+1 downto IN_LOW);
  begin
    if reset = '1' then 
      have_two_ips       <= '0';
      av_out_valid       <= '0';
      
    elsif rising_edge(clk) then
      
      if source_pixel_valid = '1' then
        ip_r             <= source_pixel;
        
        add_temp         := source_pixel + ip_r;
        av_out           <= add_temp;    --divide by 2 implicit in the type declaration. Number of bits match, but bit shifted by 1
        
        have_two_ips     <= not have_two_ips;
        av_out_valid     <= have_two_ips;
      end if;
    end if;
    
  end process;

end architecture rtl;
 

Hi TrickyDicky,

Thanks for shared the code. I will study on that and will let you know if have any problems.
Many thanks..
 

Hi TrickyDicky,

I try to compile the code given in Quartus with generic IN_HIGH : integer :=3 nad IN_LOW : integer :=-4.
Then I simulate it in ModelSim. Why the output is not same as expected? What I understand from your code is a pair of input will divide by two, right?. Or I miss understood your code? Below is the testbench code and I attach the waveform. Hope you can help,thank you.

-------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;

library ieee_proposed;
use ieee_proposed.fixed_pkg.all;

entity moving_average_tb is
end;

architecture bench of moving_average_tb is

component moving_average
generic (
IN_HIGH : integer := 3;
IN_LOW : integer := -4
);
port (
clk : in std_logic;
reset : in std_logic;
source_pixel : in sfixed(IN_HIGH downto IN_LOW);
source_pixel_valid : in std_logic;
av_out : out sfixed(IN_HIGH downto IN_LOW-1);
av_out_valid : out std_logic
);
end component;

signal clk: std_logic;
signal reset: std_logic;
signal source_pixel: sfixed(3 downto -4);
signal source_pixel_valid: std_logic;
signal av_out: sfixed(3 downto -4-1);
signal av_out_valid: std_logic ;

constant clock_period: time := 10 ns;
signal stop_the_clock: boolean;

begin
uut: moving_average generic map ( IN_HIGH => 3,
IN_LOW => -4 )
port map ( clk => clk,
reset => reset,
source_pixel => source_pixel,
source_pixel_valid => source_pixel_valid,
av_out => av_out,
av_out_valid => av_out_valid );

stimulus: process
begin

reset <= '1';
wait for 5 ns;
reset <= '0';
wait for 5 ns;

source_pixel <= "00100000";
wait for 50 ns;

source_pixel <= "01010000";
source_pixel_valid <= '1';
wait for 50 ns;

stop_the_clock <= true;
wait;
end process;

clocking: process
begin
while not stop_the_clock loop
clk <= '0', '1' after clock_period / 2;
wait for clock_period;
end loop;
wait;
end process;
end;
------------------------------------------------------------------------------------------------------------------------
 

Attachments

  • waveform.JPG
    waveform.JPG
    140.5 KB · Views: 49

that is as expected.

You're constantly inputting 5

(5+5)/2 = 5
 

Hi TrickyDicky,

How to insert different values in ModelSim? For example (6+4)/2=5.

source_pixel <= "01100000";
source_pixel <= "01000000";
source_pixel_valid <= '1';
wait for 50 ns;

I try to write like above, but the output is wrong. What is my mistake? Thank for reply..
 

the source_Pixel_valid needs to be '1' when the inputs are 1, with 1 value per clock cycle.

Try this:

Code:
ip_proc : process
begin
  source_pixel_valid <= '0';
  wait until reset = '0';
  wait until rising_edge(clk)  --sync
  
  source_pixel_valid <= '1';
  source_pixel       <= to_sfixed(6, source_pixel);

  wait until rising_edge(clk);

  source_pixel <= to_sfixed(4, source_pixel);
  --etc

  wait;
end process;
 

Hi TrickyDicky,

I have write the code given and simulate in ModelSim but the input and output is not come out.
Then, I change the code by remove the first three line (red color) as shown below and the simulation is okay. Why this error occur if I use the first three line?

Another question, from the code and waveform simulation results, the average will done on each input. So, how to write for average only for the pair of input only. For example:

input: 3,4,5,1
output: (3+4)/2, (5+1)/2

----------------------------------------------------------------
ip_proc : process
begin
source_pixel_valid <= '0';
wait until reset = '0';
wait until rising_edge(clk) --sync


source_pixel_valid <= '1';
source_pixel <= to_sfixed(6, source_pixel);

wait until rising_edge(clk);

source_pixel <= to_sfixed(4, source_pixel);
--etc

wait;
end process;
-----------------------------------------------------------------------
Thank for reply..
 

have you generated a reset somewhere?

This is a serial interface, so you have to provide the values on subsequent clock cycles, in the order 3, 4, 5, 1. You could easily modify my code to do it.
 

if you look at my process it needs a reset, because it waits until reset goes from something to '0'; thats why nothing is happening.
 

Hi TrickyDicky,

I have try to generate a reset like the code below, but the results still not occurs.
reset <= '1';
wait for 5 ns;
reset <= '0';
wait for 5 ns;
What my mistake? Thank for help..
 

The reset needs to be in a separate process, Otherwise its going to wait at line 57 forever because reset is already '0'. (now you're writing testbenches, you have to think a bit more like software - code is executed in order in a testbench- actually all VHDL is executed in order - think of a process as an infinite loop)
Or you can just write this outside a process:

reset <= '0', '1' after 5 ns;
 

Hi TrickyDicky,

For the second question in the previous post, you said I need to provide the values on subsequent clock cycles. What do you mean by subsequent clock cycle?
Thank for reply..
 

like
source_pixel <= to_sfixed(3, source_pixel);
wait until rising_edge (clk);

source_pixel <= to_sfixed(4, source_pixel);
wait until rising_edge (clk);

source_pixel <= to_sfixed(5, source_pixel);
wait until rising_edge (clk);

source_pixel <= to_sfixed(1, source_pixel);
wait until rising_edge (clk);

output will be valid on 3.5 followed by 3
 

The output when the valid output is low should be ignored. So the two outputs are 3.5 and 3
 

Hi TrickyDicky,

Thanks I get it. Know, I try to understand the process. Like your advice from the previous post which is imagine that the pixels arrive 1 at a time and then control the system to monitor the input. What I am thinking is to use a port map to control the inputs. Is it possible? I can't imagine how the input pixel will enter the average process 1 by 1 after another. Before this I declare the port of average process with 2 inputs and 1 output. Then, I only do port map to control them. Need helps, thank for reply..
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top