📄 video.vhd
字号:
-- the start of each field. (The video lines in each field are interleaved through
-- the SDRAM.)
if pixel_from_framegrabber(15) = HI then -- The video field has changed ...
pixel_cntr_x <= 0; -- so reset the pixel counter ...
-- and set the starting SDRAM address for the field.
if pixel_from_framegrabber(14) = '0' then
-- Even fields start at SDRAM address 0.
store_cntr_x <= 0;
else
-- Odd fields start at (SDRAM address 0) + (length of a video line).
store_cntr_x <= PIXELS_PER_LINE;
end if;
-- Determine the next state.
if pixel_avail = YES then
-- If another pixel is available, then initiate a read and immediately return
-- to this state to store it.
pixel_rd <= YES;
store_state_x <= store_pixel;
else
-- Otherwise, wait for another pixel to arrive.
store_state_x <= wait_for_pixel;
end if;
-- The sync bit is cleared, so store the pixel data into SDRAM.
else
store_wr <= YES; -- Initiate the store into SDRAM.
if store_wr_begun = YES then
-- The store operation has begun, so update the SDRAM address pointer.
if pixel_cntr = PIXELS_PER_LINE-1 then
-- Reached the end of the current line of video, so move the pointer
-- to the start of the next interleaved line in SDRAM.
store_cntr_x <= store_cntr+PIXELS_PER_LINE+1;
pixel_cntr_x <= 0; -- Reset the counter for the line of pixels.
else
-- Otherwise, just increment the address pointer and pixel counter.
store_cntr_x <= store_cntr+1;
pixel_cntr_x <= pixel_cntr+1;
end if;
-- Determine the next state.
if pixel_avail = YES then
-- If another pixel is available, then initiate a read and immediately return
-- to this state to store it.
pixel_rd <= YES;
store_state_x <= store_pixel;
else
-- Otherwise, wait for another pixel to arrive.
store_state_x <= wait_for_pixel;
end if;
end if;
end if;
when others =>
-- If in an erroneous state, go to a valid state.
store_state_x <= wait_for_pixel;
end case;
end process; -- End of the combinational portion of the FSM
----------------------------------------------------------------------------------------------
-- Sequential portion of the FSM.
process(clk, reset)
begin
if reset = YES then
store_cntr <= 0;
pixel_cntr <= 0;
store_state <= wait_for_pixel;
elsif rising_edge(clk) then
store_cntr <= store_cntr_x;
pixel_cntr <= pixel_cntr_x;
store_state <= store_state_x;
end if;
end process;
----------------------------------------------------------------------------------------------
-- Convert the address counter into a std_logic_vector that can be used by the SDRAM controller.
store_address <= CONV_STD_LOGIC_VECTOR(store_cntr, store_address'length);
----------------------------------------------------------------------------------------------
-- This is the dualport module that gives both the framegrabber and the VGA generator
-- access to the SDRAM.
----------------------------------------------------------------------------------------------
u1 : dualport
generic map(
PIPE_EN => true,
PORT_TIME_SLOTS => "0000000000000000", -- Give the framegrabber complete priority over the VGA.
DATA_WIDTH => DATA_WIDTH,
HADDR_WIDTH => HADDR_WIDTH
)
port map(
clk => clk,
-- Framegrabber interface attaches to port 0 and has complete priority over the VGA generator
-- since we would rather mess-up the display for a single frame-time rather than miss data
-- from the framegrabber.
rst0 => reset,
rd0 => NO,
wr0 => store_wr,
earlyOpBegun0 => store_wr_begun,
opBegun0 => open,
rdPending0 => open,
rdDone0 => open,
done0 => open,
hAddr0 => store_address,
hDIn0 => pixel_from_framegrabber,
hDOut0 => open,
status0 => open,
-- VGA interface
rst1 => reset,
rd1 => read_rd,
wr1 => NO,
earlyOpBegun1 => read_rd_begun,
opBegun1 => open,
rdPending1 => open,
rdDone1 => read_rd_done,
done1 => open,
hAddr1 => read_address,
hDIn1 => "0000000000000000",
hDOut1 => pixel_to_vga,
status1 => open,
-- Connections to the SDRAM controller.
rst => rst_i,
rd => rd_i,
wr => wr_i,
earlyOpBegun => earlyOpBegun_i,
opBegun => opBegun_i,
rdPending => rdPending_i,
rdDone => rdDone_i,
done => done_i,
hAddr => hAddr_i,
hDIn => hDIn_i,
hDOut => hDOut_i,
status => status_i
);
----------------------------------------------------------------------------------------------
-- Instantiate the SDRAM controller that connects to the dualport
-- module and interfaces to the external SDRAM chip.
----------------------------------------------------------------------------------------------
u2 : xsaSDRAMCntl
generic map(
FREQ => MASTER_CLK_FREQ,
CLK_DIV => MASTER_CLK_DIV,
PIPE_EN => true, -- Enable pipelining for maximum SDRAM bandwidth.
MULTIPLE_ACTIVE_ROWS => true, -- Allow multiple active rows in SDRAM for maximum bandwidth.
MAX_NOP => 1000000, -- Disable self-refresh since it takes too long to re-awaken the SDRAM with video timing.
DATA_WIDTH => DATA_WIDTH,
NROWS => SDRAM_NROWS,
NCOLS => SDRAM_NCOLS,
HADDR_WIDTH => HADDR_WIDTH,
SADDR_WIDTH => SADDR_WIDTH
)
port map(
clk => clk_in,
clk1x => clk,
rst => rst_i,
rd => rd_i,
wr => wr_i,
earlyOpBegun => earlyOpBegun_i,
opBegun => opBegun_i,
rdPending => rdPending_i,
done => done_i,
rdDone => rdDone_i,
hAddr => hAddr_i,
hDIn => hDIn_i,
hDOut => hDOut_i,
status => status_i,
sclkfb => sclkfb,
sclk => sclk,
cke => cke,
cs_n => cs_n,
ras_n => ras_n,
cas_n => cas_n,
we_n => we_n,
ba => ba,
sAddr => sAddr,
sData => sData,
dqmh => dqmh,
dqml => dqml
);
----------------------------------------------------------------------------------------------
-- The VGA generator gets data from the SDRAM and displays it on a monitor.
----------------------------------------------------------------------------------------------
u3 : vga
generic map (
FREQ => 50_000,
PIXEL_WIDTH => PIXEL_WIDTH,
PIXELS_PER_LINE => PIXELS_PER_LINE,
LINES_PER_FRAME => LINES_PER_FRAME,
NUM_RGB_BITS => NUM_RGB_BITS,
FIT_TO_SCREEN => FIT_TO_SCREEN
)
port map(
rst => reset,
clk => clk,
wr => read_rd_done,
pixel_data_in => pixel_to_vga,
full => vga_full,
eof => vga_eof,
r => r,
g => g,
b => b,
hsync_n => hsync_n,
vsync_n => vsync_n,
blank => open
);
----------------------------------------------------------------------------------------------
-- Read pixels from the SDRAM as long as the VGA FIFO buffer is not full.
read_rd <= not(vga_full);
----------------------------------------------------------------------------------------------
-- Update the address counter used by the VGA generator to get pixels from SDRAM.
----------------------------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if vga_eof = YES then
read_cntr <= 0; -- Reset the address at the end of a video frame.
elsif read_rd_begun = YES then
read_cntr <= read_cntr + 1; -- Go to the next address once the read of the current address has begun.
end if;
end if;
end process;
----------------------------------------------------------------------------------------------
-- Convert the address counter into a std_logic_vector that can be used by the SDRAM controller.
read_address <= CONV_STD_LOGIC_VECTOR(read_cntr, read_address'length);
----------------------------------------------------------------------------------------------
-- This is the parallel port -> I2C interface that is used to initialize the video decoder
-- from the PC.
----------------------------------------------------------------------------------------------
scl_out <= lp_d(0);
sda_out <= lp_d(1);
lp_s(3) <= scl_in;
lp_s(4) <= sda_in;
scl <= '0' when scl_out = '0' else 'Z';
sda <= '0' when sda_out = '0' else 'Z';
scl_in <= scl;
sda_in <= sda;
end arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -