get vpos and hpos out vsync and hsync - vhdl

For a project i got a screen with a resolution of 1024*600. For the project i need a squarre of 20px *20px with a red color. Im trying to get my verticale pos en horizontale pos out of the hsync en vsync pulse but this doesn't work. Have anyone a solution?
process(int_hsync, int_vsync)
begin
if Rising_Edge(int_vsync) then
vsync <= 0;
elsif Rising_Edge(in_clk) then
vsync <= vsync+1;
end if;
if Rising_Edge(int_hsync) then
hsync <= 0;
elsif Rising_Edge(in_clk) then
hsync <= hsync+1;
end if;
end process;
process(in_clk)
begin
if Rising_Edge(in_clk) then
if hsync < 20 and vsync <20 then
int_pixel <= X"0000ff";
else
int_pixel <= X"ff0000";
end if;
end if;
end process;

Without some additional details it is very difficult to tell what you are trying to do.
However, I did notice that your process is only sensitive to int_hsync and int_vsync, yet you are looking for a rising_edge of in_clk. You should do an edge detect similar to this, instead (assuming that in_clk is much faster than hsync and vsync):
process(in_clk)
begin
if rising_edge(in_clk) then
int_vsync_dly <= int_vsync;
int_hsync_dly <= int_hsync;
if int_vsync = '1' and int_vsync_dly = '0' then -- rising edge detect
vsync <= 0;
else
vsync <= vsync+1;
end if;
if int_hsync = '1' and int_hsync_dly = '0' then -- rising edge detect
hsync <= 0;
else
hsync <= hsync+1;
end if;
end if;
end process;
This increments vsync and hsync counters every time a rising edge of the respective trigger signals is observed. Do make sure that the inputs are properly registered before the edge detection to help avoid meta-stable cases.

Related

Interfacing output to a DAC - VHDL

I am trying to interface the output of my FPGA onto a DAC. I am using the PmodDA2 DAC. The trouble I am having is working out how to output the data from a 16bit register into 1 bit per clock cycle.
I have studied the timing diagram and understand that CS needs to send a pulse before data transmission begins.
I have tried using the necessary resets and other features as applicable within my design as a whole.
I tried implementing a count to cycle between 0 to 16/17 and when it was at the beginning it would set CS to high and begin transmission. However I did not believe this would be at all the correct way to do it.
architecture Behavioral of DAC is
signal count : integer range 0 to 15;
signal selected : std_logic;
signal data_storage : std_logic_vector(15 downto 0);
begin
process(D_DAC, CE_DAC, RES_DAC, RES_DAC, data_storage)
begin
if RES_DAC = '1' then
data_storage <= "0000000000000000";
end if;
if rising_edge(CLK_DAC) then
if CE_DAC = '1' then
data_storage <= D_DAC;
end if;
end if;
end if;
end process ;
CS_DAC <= CE_DAC;
SCLK_DAC <= CLK_DAC;
DATA1_DAC <= data_storage;
end Behavioral;
I'm getting myself very confused over this.
I'd appreciate any help.
************************EDIT************************
I have had another go at implementing the counter...
process(D_DAC, CE_DAC, CLK_DAC, RES_DAC, data_storage)
begin
if RES_DAC = '1' then
data_storage <= "0000000000000000";
cound <= 0;
selected <= '0';
elsif rising_edge(CLK_DAC) then
if CE_DAC = '1' then
if count = 0 then
selected <= '1';
end if;
if selected = 1 then
if count = 15 then
count <= 0;
selected <= '0';
else
count <= count + 1;
data_storage <= D_DAC;
end if;
end if;
end if;
end if;
end process ;
CS_DAC <= CE_DAC;
SCLK_DAC <= CLK_DAC;
DATA1_DAC <= data_storage;
end Behavioral;

VHDL Synthesis Error and Code Suggestions [duplicate]

I've a module that have a 8bit input and a serial output, I want to serialize input data and synchronize it with a clock.
I want to set my data when falling edge then wait when clock rise, when clock fall again I set another data. I don't want to connect the directly reference clock to the output because when I don't use this module I want a 1 state on clock output.
I've tried this code:
process(Clock, ModuleReset)
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
elsif rising_edge(Clock) then
OutCK <= '1';
end if;
end process;
The synthesizer gives me this error:
"Asynchronous load of non-constant data for SCK is not supported"
When I separate the code in two blocks like this:
process(Clock, ModuleReset)
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
end process;
process(Clock)
if rising_edge(Clock) then
OutCK <= '1';
end if;
end process;
I have these two errors:
"Multiple non tristate drivers for net SCK"
"Unresolved tristate drivers for net SCK"
Another code I've tried is:
process(Clock, ModuleReset)
if ModuleEN = '1' then
OutCK <= Clock;
end if;
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
end if;
end process;
But the output clock looks strange with a different frequency.
Your last idea, which I understand ended up working for you, is sub-optimal. If your clock is slow, it should be fine, but I suggest you fix it nevertheless.
if ModuleEN = '1' then
OutCK <= Clock;
else
OutCK <= '1';
end if;
Yields combinational logic with the clock signals for the output. Having the clock used as a logic signal is never recommended, since clocks use clock paths which doesn't route well to general routing resources. The output signal will have potential glitches (very bad for an output interface!) and large delay/skew.
Your first approach, to use a DDR register to forward the clock, is indeed the correct and best approach. With this scheme, your clock only use clock paths, and if both the registers outputing the clock and data are situated in IO blocks, they will have the same output delay with very little skew.
You didn't specify the technology you're using, but I suggest you lookup how to write code that maps to DDR register for your synthesizer. Alternatively, you can manually instantiate the DDR output register primitive, likely ODDR for Xilinx or ALTDDIO_OUT for altera.
The problem with your attempts is indeed that you have multiple drivers for the same signal, or that you assign a signal on both rising and falling edge of a clock. This is not synthesizable.
Try this:
process(Clock, ModuleReset, ModuleEN)
begin
if ModuleEN = '1' then
OutCK <= Clock;
else
OutCK <= '1';
end if;
if ModuleReset = '0' then
OutData <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutData <= Data(counter);
end if;
end process;

Update data when clock goes low - VHDL

I need to set output data when clock goes low and not to next rising_edge, I've modified a code to work in this way, but I've this warning:
Clock on register Empty tied to a constant
Clock on register Full tied to a constant
This is the code:
elsif rising_edge(Clock) then
if (Head = Tail) then
if Looped then
FullVar := '1';
else
EmptyVar := '1';
end if;
else
EmptyVar := '0';
FullVar := '0';
end if;
else
Full <= FullVar;
Empty <= EmptyVar;
end if;
end process;
To eliminate this warning I've modified code in this way:
elsif rising_edge(Clock) then
if (Head = Tail) then
if Looped then
FullVar := '1';
else
EmptyVar := '1';
end if;
else
EmptyVar := '0';
FullVar := '0';
end if;
end if;
Full <= FullVar;
Empty <= EmptyVar;
end process;
But when I compile code and simulate I've a higher delay before flag is asserted(in the corrected code without warnings). Why is that? Also, code works, but it's correct this type of code or data should be always updated when rising_edge?
Yes, you should always use rising_edge(Clock), unless you 'really' need a second clock domain. In your case you do not need a second clock domain.
There is also no reason to use variables in you example. The following code will raise Empty after a rising_edge of the clock, if Head is equal to Tail and Looped is '1' before the rising edge.
check : process (Clock)
if rising_edge(Clock) then
if Head = Tail then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
else
Empty <= '0';
Full <= '0';
end if;
end if;
end process;
If you want the have Empty raise before the rising edge you should do this combinatorially, like this:
check : process (Head,Tail,Looped)
Empty <= '0';
Full <= '0';
if Head = Tail then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
end process;
I hope this helps.

Drive input clock to output

I've a module that have a 8bit input and a serial output, I want to serialize input data and synchronize it with a clock.
I want to set my data when falling edge then wait when clock rise, when clock fall again I set another data. I don't want to connect the directly reference clock to the output because when I don't use this module I want a 1 state on clock output.
I've tried this code:
process(Clock, ModuleReset)
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
elsif rising_edge(Clock) then
OutCK <= '1';
end if;
end process;
The synthesizer gives me this error:
"Asynchronous load of non-constant data for SCK is not supported"
When I separate the code in two blocks like this:
process(Clock, ModuleReset)
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
end process;
process(Clock)
if rising_edge(Clock) then
OutCK <= '1';
end if;
end process;
I have these two errors:
"Multiple non tristate drivers for net SCK"
"Unresolved tristate drivers for net SCK"
Another code I've tried is:
process(Clock, ModuleReset)
if ModuleEN = '1' then
OutCK <= Clock;
end if;
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
end if;
end process;
But the output clock looks strange with a different frequency.
Your last idea, which I understand ended up working for you, is sub-optimal. If your clock is slow, it should be fine, but I suggest you fix it nevertheless.
if ModuleEN = '1' then
OutCK <= Clock;
else
OutCK <= '1';
end if;
Yields combinational logic with the clock signals for the output. Having the clock used as a logic signal is never recommended, since clocks use clock paths which doesn't route well to general routing resources. The output signal will have potential glitches (very bad for an output interface!) and large delay/skew.
Your first approach, to use a DDR register to forward the clock, is indeed the correct and best approach. With this scheme, your clock only use clock paths, and if both the registers outputing the clock and data are situated in IO blocks, they will have the same output delay with very little skew.
You didn't specify the technology you're using, but I suggest you lookup how to write code that maps to DDR register for your synthesizer. Alternatively, you can manually instantiate the DDR output register primitive, likely ODDR for Xilinx or ALTDDIO_OUT for altera.
The problem with your attempts is indeed that you have multiple drivers for the same signal, or that you assign a signal on both rising and falling edge of a clock. This is not synthesizable.
Try this:
process(Clock, ModuleReset, ModuleEN)
begin
if ModuleEN = '1' then
OutCK <= Clock;
else
OutCK <= '1';
end if;
if ModuleReset = '0' then
OutData <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutData <= Data(counter);
end if;
end process;

Handling Interrupt in VHDL

We are using OR1200 for our project and we would like to assign an interrupt to the 8th button of FPGA Board. Here is the code to generate interrupt:
inrpt: process(CLK_I, RST_I)
begin
if RST_I = '1' then
butt_int_pul <= '0';
butt_int_tmp <= '0';
elsif rising_edge(CLK_I) then
if(DATA_I(8) = '1' and butt_int_tmp = '0') then
butt_int_pul <= '1';
else
butt_int_pul <= '0';
end if;
butt_int_tmp <= DATA_I(8);
end if;
end process inrpt;
process(CLK_I, RST_I)
begin
if RST_I = '1' then
butt_int <= '0';
elsif butt_int_pul = '1' then
butt_int <= '1';
elsif clear_int = '1' then
butt_int <= '0';
end if;
end process;
We only want this interrupt to be handled only once (holding the button should not call the interrupt again), that's why we included a flag to check this (butt_int_tmp).
The problem is that the interrupt call is not stable. It does not call each time we press the button. When we remove the flag, it works, but in this case, it is handled as many as we hold the button.
What are we doing wrong?
To start with, that second process is not properly written. It should have a structure equivalent to the first process (i.e., if(rising_edge(CLK_I)) surrounding all but the reset logic). You are currently describing a latch with multiple enable signals and wrong sensitivity list.
Moving on, there's no real reason you need that second process at all. You just need one register to act as interrupt (butt_int), and one to keep track of the previous state of the button (butt_prev). The interrupt is triggered for one cycle when DATA_I(8) is '1' while butt_prev is '0' (i.e., the button changed from not-pressed to pressed).
process(CLK_I, RST_I) begin
if(RST_I='1') then
butt_prev <= '0';
butt_int <= '0';
elsif(rising_edge(CLK_I)) then
if(DATA_I(8)='1' and butt_prev='0') then
butt_int <= '1';
else
butt_int <= '0';
end if;
butt_prev <= DATA_I(8);
end if;
end process;
Note that this will only work if your button is properly debounced, otherwise you are likely to get multiple interrupts triggered when you press (or even release) the button.
Its best not to think about interrupts. As you're targetting an FPGA, you're describing digital logic, not a software processor.
There a numerous way to build a circuit with the behaviour you want.
The simplest is probably a re-timed latch
signal latched_button : std_logic;
signal meta_chain : std_logic_vector(2 downto 0);
p_async_latch: process(rst_i,data(8))
begin
if rst_i = '1' then
latched_button <= '0';
elsif data(8) = '1' then
latched_button <= '1';
end if;
end process;
p_meta_chain: process(rst_i,clk_i)
begin
if rst_i = '1' then
meta_chain <= (others => '0');
elsif rising_edge(clk_i) then
meta_chain <= meta_chain(1 downto 0) & latched_button;
end if;
end process;
button_int <= '1' when meta_chain(2 downto 1) = "01" else '0';
This causes the button press to be latched asynchronously. The latched signal is then clocked along a shift register, and the interrupt is only valid for one cycle, which is the first clock cycle that the latch is seen on the clock domain.

Resources