Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

constant manipulation in VHDL statement

Hi,

I am puzzled by the result of a VHDL code and hope someone could help understand the problem.

......

constant PERIOD : integer := 1000;

constant A : integer := 4;

constant B : integer := 23;

......

......

process

variable count : integer := 0;

......

......

if count < (PERIOD* (A+B )) then

It appears that the behavior of the statement above is not as I expected: "if count < (1000 * (4+23)) then".

1. Where did my 'logic' go wrong?

2. How do I find out how VHDL codes are parsed in Quartus?

Thanks

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Are you simulating or synthesizing? If you write "if count < 27000 then" the code works different?

    Please, place the whole vhdl code to understand it better.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Are you simulating or synthesizing? If you write "if count < 27000 then" the code works different?

    Please, place the whole vhdl code to understand it better.

    --- Quote End ---

    I guess I was synthesizing. I compiled the project, download the sof to DE0-NANO to run it.

    Here is the VHDL code. Thank you for the help.

    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    LIBRARY work;
    ENTITY square IS 
    	PORT
    	(
    		clk :  IN  STD_LOGIC;
    		vs:	IN STD_LOGIC;			-- vertial sync
    		wr_req:	OUT STD_LOGIC;		-- write request
    		data:	OUT STD_LOGIC_VECTOR(7 downto 0)
    	);
    END square;
    ARCHITECTURE bdf_type OF square IS 
    	constant	HSYNC_PERIOD	: integer := 1056;			-- LCD horizontal period is 1056 clock cycles
    	constant	HSYNC_LOW	: integer := 128;				-- LCD horizontal sync signal pulse width is 128 LCD clock cycles
    	constant	H_FRONT_PORCH	: integer := 64;				-- Horizontal front porch = 64 pixels
    	constant	H_BACK_PORCH	: integer := 64;				-- Horizontal back porch = 64 pixels
    	constant	H_PIXELS	: integer := 800;					-- Horizontal display period = 800 pixels
    	
    	constant	VSYNC_PERIOD	: integer := 666 * HSYNC_PERIOD;	-- LCD vertical period is 666 horizontal line
    	constant	VSYNC_LOW	: integer := 4 * HSYNC_PERIOD;		-- LCD vertical sync signal pulse width is 4 horizontal lines
    	constant	V_FRONT_PORCH	: integer := 39 * HSYNC_PERIOD;	-- Vertical front porch = 39 lines
    	constant	V_BACK_PORCH	: integer := 23 * HSYNC_PERIOD;	-- Vertical back porch = 23 lines
    	constant	V_LINES	: integer := 600 * HSYNC_PERIOD;			-- Vertical display period = 600 lines
    	
    	constant	RED	: STD_LOGIC_VECTOR(7 downto 0) := x"0a";
    	constant	GREEN	: STD_LOGIC_VECTOR(7 downto 0) := x"0b";
    	constant	YELLOW	: STD_LOGIC_VECTOR(7 downto 0) := x"0c";
    	constant	BLUE	: STD_LOGIC_VECTOR(7 downto 0) := x"0d";
    	constant	PURPLE	: STD_LOGIC_VECTOR(7 downto 0) := x"0e";
    	constant	TURQUOISE	: STD_LOGIC_VECTOR(7 downto 0) := x"0f";
    	constant	WHITE	: STD_LOGIC_VECTOR(7 downto 0) := x"10";
    	constant	PIXEL_OFF	: STD_LOGIC_VECTOR(7 downto 0) := x"01";
    	
    BEGIN 
    --	Input:	
    --		none
    --	Clock:	
    --		LCDclk - LCD clock @ 10 MHz
    --	Output:
    --		LCDHsyncN - signal, LCD horizontal timing 
    --	Description:
    --		This process generates LCD horizontal timing signal: 480 clock cycles high and 128 clock cycles low
    PROCESS(clk, vs)
    	variable p_count : integer range 0 to H_PIXELS;
    	variable clk_count : integer := 0;
    	
    	BEGIN
    	if rising_edge(clk) then
    		if vs = '0' then
    --			clk_count := ((HSYNC_PERIOD * VSYNC_LOW) - 1);		-- Vertical sync pulse width is 4 lines
    			clk_count := (1056*4) - 1;		-- Vertical sync pulse width is 4 lines
    			wr_req <= '0';
    		else
    			clk_count := clk_count + 1;
    --			if clk_count < (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) then
    			if clk_count < (1056 * (4+23)) then
    				-- vertical blank period; do nothing
    				p_count := 0;
    				wr_req <= '0';
    --			elsif clk_count < (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH+1)) then
    			elsif clk_count < (1056 * (4+23+1)) then
    				-- 1st display line
    --				if clk_count = (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) then
    				if clk_count = (1056 * (4+23)) then
    					-- 1st pixel of the line
    					p_count := 0;	-- reset pixel count
    					wr_req <= '1';
    --				elsif clk_count < ((HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) + H_PIXELS) then
    				elsif clk_count < ((1056 * (4+23)) + 800) then
    					data <= GREEN;
    					wr_req <= '1';
    				else
    					wr_req <= '0';
    					data <= PIXEL_OFF;
    				end if;
    			else
    				data <= PIXEL_OFF;
    				wr_req <= '0';
    			end if;
    		end if;
    	end if;
    	END PROCESS;
    END bdf_type;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Listed below is the complete code. "if clk_count < (1056 * (4+23))" works but "if clk_count < (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH))" does not.

    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    LIBRARY work;
    ENTITY square IS 
    	PORT
    	(
    		clk :  IN  STD_LOGIC;
    		vs:	IN STD_LOGIC;			-- vertial sync
    		wr_req:	OUT STD_LOGIC;		-- write request
    		data:	OUT STD_LOGIC_VECTOR(7 downto 0)
    	);
    END square;
    ARCHITECTURE bdf_type OF square IS 
    	constant	HSYNC_PERIOD	: integer := 1056;					-- LCD horizontal period is 1056 clock cycles
    	constant	HSYNC_LOW	: integer := 128;							-- LCD horizontal sync signal pulse width is 128 LCD clock cycles
    	constant	H_FRONT_PORCH	: integer := 64;						-- Horizontal front porch = 64 pixels
    	constant	H_BACK_PORCH	: integer := 64;						-- Horizontal back porch = 64 pixels
    	constant	H_PIXELS	: integer := 800;								-- Horizontal display period = 800 pixels
    	
    --	constant	DPL_LINES	: integer := 234;		-- each LCD display frame consists of 234 horizontal lines
    --	constant	FB_LINES		: integer := 28;		-- LCD vertical flyback period is 28 horizontal line
    	constant	VSYNC_PERIOD	: integer := 666 * HSYNC_PERIOD;	-- LCD vertical period is 666 horizontal line
    	constant	VSYNC_LOW	: integer := 4 * HSYNC_PERIOD;		-- LCD vertical sync signal pulse width is 4 horizontal lines
    	constant	V_FRONT_PORCH	: integer := 39 * HSYNC_PERIOD;	-- Vertical front porch = 39 lines
    	constant	V_BACK_PORCH	: integer := 23 * HSYNC_PERIOD;	-- Vertical back porch = 23 lines
    	constant	V_LINES	: integer := 600 * HSYNC_PERIOD;			-- Vertical display period = 600 lines
    	
    	constant	RED	: STD_LOGIC_VECTOR(7 downto 0) := x"0a";
    	constant	GREEN	: STD_LOGIC_VECTOR(7 downto 0) := x"0b";
    	constant	YELLOW	: STD_LOGIC_VECTOR(7 downto 0) := x"0c";
    	constant	BLUE	: STD_LOGIC_VECTOR(7 downto 0) := x"0d";
    	constant	PURPLE	: STD_LOGIC_VECTOR(7 downto 0) := x"0e";
    	constant	TURQUOISE	: STD_LOGIC_VECTOR(7 downto 0) := x"0f";
    	constant	WHITE	: STD_LOGIC_VECTOR(7 downto 0) := x"10";
    	constant	PIXEL_OFF	: STD_LOGIC_VECTOR(7 downto 0) := x"01";
    	
    BEGIN 
    --	Input:	
    --		none
    --	Clock:	
    --		LCDclk - LCD clock @ 10 MHz
    --	Output:
    --		LCDHsyncN - signal, LCD horizontal timing 
    --	Description:
    --		This process generates LCD horizontal timing signal: 480 clock cycles high and 128 clock cycles low
    PROCESS(clk, vs)
    	variable p_count : integer range 0 to H_PIXELS;
    	variable clk_count : integer := 0;
    	
    	BEGIN
    	if rising_edge(clk) then
    		if vs = '0' then
    --			clk_count := ((HSYNC_PERIOD * VSYNC_LOW) - 1);		-- Vertical sync pulse width is 4 lines
    			clk_count := (1056*4) - 1;		-- Vertical sync pulse width is 4 lines
    			wr_req <= '0';
    		else
    			clk_count := clk_count + 1;
    --			if clk_count < (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) then
    			if clk_count < (1056 * (4+23)) then
    				-- vertical blank period; do nothing
    				p_count := 0;
    				wr_req <= '0';
    --			elsif clk_count < (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH+1)) then
    			elsif clk_count < (1056 * (4+23+1)) then
    				-- 1st display line
    --				if clk_count = (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) then
    				if clk_count = (1056 * (4+23)) then
    					-- 1st pixel of the line
    					p_count := 0;	-- reset pixel count
    					wr_req <= '1';
    --				elsif clk_count < ((HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) + H_PIXELS) then
    				elsif clk_count < ((1056 * (4+23)) + 800) then
    					data <= GREEN;
    					wr_req <= '1';
    				else
    					wr_req <= '0';
    					data <= PIXEL_OFF;
    				end if;
    			else
    				data <= PIXEL_OFF;
    				wr_req <= '0';
    			end if;
    		end if;
    	end if;
    	END PROCESS;
    END bdf_type;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    VSYNC_LOW and V_BACK_PORCH are respectively defined as 4 * HSYNC_PERIOD and 23 * HSYNC_PERIOD, so (1056 * (4+23)) and (HSYNC_PERIOD * (VSYNC_LOW+V_BACK_PORCH)) are far from equal. I assume you meant just (VSYNC_LOW+V_BACK_PORCH) as a comparison value.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This kind of mistake happens to anyone ;)

    But this shows how important it is to give all your code when you are encountering a strange problem and ask for help!