commit 5fe74b3778ec4f58f628a6f140af1e9fa9a08eac Author: root Date: Fri Oct 18 11:08:40 2013 +0100 with_line_doubler diff --git a/bbc_micro_de1.vhd b/bbc_micro_de1.vhd index e109c36..d78fe69 100644 --- a/bbc_micro_de1.vhd +++ b/bbc_micro_de1.vhd @@ -279,6 +279,30 @@ port ( ); end component; + +component line_doubler is +port ( + CLOCK : in std_logic; + -- Clock enable qualifies display cycles (interleaved with CPU cycles) + CLKEN : in std_logic; + nRESET : in std_logic; + + -- Video in (teletext mode) + R_IN : in std_logic; + G_IN : in std_logic; + B_IN : in std_logic; + HS_IN : in std_logic; + VS_IN : in std_logic; + + -- Video out + R_OUT : out std_logic; + G_OUT : out std_logic; + B_OUT : out std_logic; + HS_OUT : out std_logic; + VS_OUT : out std_logic + ); +end component; + -------------------------------- -- SAA5050 Teletext Generator -------------------------------- @@ -610,6 +634,13 @@ signal r_out : std_logic; signal g_out : std_logic; signal b_out : std_logic; +-- line doubler signals +signal ld_r_out : std_logic; +signal ld_g_out : std_logic; +signal ld_b_out : std_logic; +signal ld_hsync : std_logic; +signal ld_vsync : std_logic; + -- SAA5050 signals signal ttxt_glr : std_logic; signal ttxt_dew : std_logic; @@ -801,6 +832,16 @@ begin r_out, g_out, b_out ); + ld : line_doubler port map ( + clock, + vid_clken, + reset_n, + r_out, g_out, b_out, + crtc_hsync,crtc_vsync, + ld_r_out,ld_g_out,ld_b_out, + ld_hsync, ld_vsync + ); + teletext : saa5050 port map ( CLOCK_24(0), -- This runs at 6 MHz, which we can't derive from the 32 MHz clock ttxt_clken, @@ -1182,12 +1223,16 @@ begin ttxt_crs <= not crtc_ra(0); ttxt_lose <= crtc_de; + + -- line doubler + + -- CRTC drives video out (CSYNC on HSYNC output, VSYNC high) - VGA_HS <= not (crtc_hsync xor crtc_vsync); - VGA_VS <= '1'; - VGA_R <= r_out & r_out & r_out & r_out; - VGA_G <= g_out & g_out & g_out & g_out; - VGA_B <= b_out & b_out & b_out & b_out; + VGA_HS <= ld_hsync; + VGA_VS <= ld_vsync; + VGA_R <= (others => ld_r_out); + VGA_G <= (others => ld_g_out); + VGA_B <= (others => ld_b_out); -- Connections to System VIA -- ADC diff --git a/line_buffer.qip b/line_buffer.qip new file mode 100644 index 0000000..5a031a0 --- /dev/null +++ b/line_buffer.qip @@ -0,0 +1,5 @@ +set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" +set_global_assignment -name IP_TOOL_VERSION "13.0" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "line_buffer.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "line_buffer.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "line_buffer.cmp"] diff --git a/line_buffer.vhd b/line_buffer.vhd new file mode 100644 index 0000000..5ca9fca --- /dev/null +++ b/line_buffer.vhd @@ -0,0 +1,242 @@ +-- megafunction wizard: %RAM: 2-PORT% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altsyncram + +-- ============================================================ +-- File Name: line_buffer.vhd +-- Megafunction Name(s): +-- altsyncram +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 13.0.1 Build 232 06/12/2013 SP 1 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2013 Altera Corporation +--Your use of Altera Corporation's design tools, logic functions +--and other software and tools, and its AMPP partner logic +--functions, and any output files from any of the foregoing +--(including device programming or simulation files), and any +--associated documentation or information are expressly subject +--to the terms and conditions of the Altera Program License +--Subscription Agreement, Altera MegaCore Function License +--Agreement, or other applicable license agreement, including, +--without limitation, that your use is for the sole purpose of +--programming logic devices manufactured by Altera and sold by +--Altera or its authorized distributors. Please refer to the +--applicable agreement for further details. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY line_buffer IS + PORT + ( + data : IN STD_LOGIC_VECTOR (3 DOWNTO 0); + rdaddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + rdclock : IN STD_LOGIC ; + rdclocken : IN STD_LOGIC := '1'; + wraddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + wrclock : IN STD_LOGIC := '1'; + wrclocken : IN STD_LOGIC := '1'; + wren : IN STD_LOGIC := '0'; + q : OUT STD_LOGIC_VECTOR (3 DOWNTO 0) + ); +END line_buffer; + + +ARCHITECTURE SYN OF line_buffer IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (3 DOWNTO 0); + + + + COMPONENT altsyncram + GENERIC ( + address_reg_b : STRING; + clock_enable_input_a : STRING; + clock_enable_input_b : STRING; + clock_enable_output_a : STRING; + clock_enable_output_b : STRING; + intended_device_family : STRING; + lpm_type : STRING; + numwords_a : NATURAL; + numwords_b : NATURAL; + operation_mode : STRING; + outdata_aclr_b : STRING; + outdata_reg_b : STRING; + power_up_uninitialized : STRING; + widthad_a : NATURAL; + widthad_b : NATURAL; + width_a : NATURAL; + width_b : NATURAL; + width_byteena_a : NATURAL + ); + PORT ( + clock0 : IN STD_LOGIC ; + clocken1 : IN STD_LOGIC ; + wren_a : IN STD_LOGIC ; + address_b : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + clock1 : IN STD_LOGIC ; + clocken0 : IN STD_LOGIC ; + address_a : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + data_a : IN STD_LOGIC_VECTOR (3 DOWNTO 0); + q_b : OUT STD_LOGIC_VECTOR (3 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(3 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_reg_b => "CLOCK1", + clock_enable_input_a => "NORMAL", + clock_enable_input_b => "NORMAL", + clock_enable_output_a => "BYPASS", + clock_enable_output_b => "NORMAL", + intended_device_family => "Cyclone II", + lpm_type => "altsyncram", + numwords_a => 1024, + numwords_b => 1024, + operation_mode => "DUAL_PORT", + outdata_aclr_b => "NONE", + outdata_reg_b => "CLOCK1", + power_up_uninitialized => "TRUE", + widthad_a => 10, + widthad_b => 10, + width_a => 4, + width_b => 4, + width_byteena_a => 1 + ) + PORT MAP ( + clock0 => wrclock, + clocken1 => rdclocken, + wren_a => wren, + address_b => rdaddress, + clock1 => rdclock, + clocken0 => wrclocken, + address_a => wraddress, + data_a => data, + q_b => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "1" +-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "1" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "1" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "1" +-- Retrieval info: PRIVATE: CLRdata NUMERIC "0" +-- Retrieval info: PRIVATE: CLRq NUMERIC "0" +-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +-- Retrieval info: PRIVATE: CLRrren NUMERIC "0" +-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +-- Retrieval info: PRIVATE: CLRwren NUMERIC "0" +-- Retrieval info: PRIVATE: Clock NUMERIC "1" +-- Retrieval info: PRIVATE: Clock_A NUMERIC "0" +-- Retrieval info: PRIVATE: Clock_B NUMERIC "0" +-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "1" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II" +-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096" +-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +-- Retrieval info: PRIVATE: MIFfilename STRING "" +-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1" +-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +-- Retrieval info: PRIVATE: REGdata NUMERIC "1" +-- Retrieval info: PRIVATE: REGq NUMERIC "0" +-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +-- Retrieval info: PRIVATE: REGrren NUMERIC "1" +-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +-- Retrieval info: PRIVATE: REGwren NUMERIC "1" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +-- Retrieval info: PRIVATE: VarWidth NUMERIC "0" +-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "4" +-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "4" +-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "4" +-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "4" +-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: enable NUMERIC "1" +-- Retrieval info: PRIVATE: rden NUMERIC "0" +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "NORMAL" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "NORMAL" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "NORMAL" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024" +-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "1024" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK1" +-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "TRUE" +-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10" +-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "10" +-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "4" +-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "4" +-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +-- Retrieval info: USED_PORT: data 0 0 4 0 INPUT NODEFVAL "data[3..0]" +-- Retrieval info: USED_PORT: q 0 0 4 0 OUTPUT NODEFVAL "q[3..0]" +-- Retrieval info: USED_PORT: rdaddress 0 0 10 0 INPUT NODEFVAL "rdaddress[9..0]" +-- Retrieval info: USED_PORT: rdclock 0 0 0 0 INPUT NODEFVAL "rdclock" +-- Retrieval info: USED_PORT: rdclocken 0 0 0 0 INPUT VCC "rdclocken" +-- Retrieval info: USED_PORT: wraddress 0 0 10 0 INPUT NODEFVAL "wraddress[9..0]" +-- Retrieval info: USED_PORT: wrclock 0 0 0 0 INPUT VCC "wrclock" +-- Retrieval info: USED_PORT: wrclocken 0 0 0 0 INPUT VCC "wrclocken" +-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +-- Retrieval info: CONNECT: @address_a 0 0 10 0 wraddress 0 0 10 0 +-- Retrieval info: CONNECT: @address_b 0 0 10 0 rdaddress 0 0 10 0 +-- Retrieval info: CONNECT: @clock0 0 0 0 0 wrclock 0 0 0 0 +-- Retrieval info: CONNECT: @clock1 0 0 0 0 rdclock 0 0 0 0 +-- Retrieval info: CONNECT: @clocken0 0 0 0 0 wrclocken 0 0 0 0 +-- Retrieval info: CONNECT: @clocken1 0 0 0 0 rdclocken 0 0 0 0 +-- Retrieval info: CONNECT: @data_a 0 0 4 0 data 0 0 4 0 +-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +-- Retrieval info: CONNECT: q 0 0 4 0 @q_b 0 0 4 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL line_buffer.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL line_buffer.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL line_buffer.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL line_buffer.bsf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL line_buffer_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/line_doubler.vhd b/line_doubler.vhd new file mode 100644 index 0000000..4c444c1 --- /dev/null +++ b/line_doubler.vhd @@ -0,0 +1,98 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity line_doubler is +port ( + CLOCK : in std_logic; + -- Clock enable qualifies display cycles (interleaved with CPU cycles) + CLKEN : in std_logic; + nRESET : in std_logic; + + -- Video in (teletext mode) + R_IN : in std_logic; + G_IN : in std_logic; + B_IN : in std_logic; + HS_IN : in std_logic; + VS_IN : in std_logic; + + -- Video out + R_OUT : out std_logic; + G_OUT : out std_logic; + B_OUT : out std_logic; + HS_OUT : out std_logic; + VS_OUT : out std_logic + ); +end entity; + +architecture rtl of line_doubler is + +component line_buffer is + PORT + ( + data : IN STD_LOGIC_VECTOR (3 DOWNTO 0); + rdaddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + rdclock : IN STD_LOGIC ; + rdclocken : IN STD_LOGIC := '1'; + wraddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0); + wrclock : IN STD_LOGIC := '1'; + wrclocken : IN STD_LOGIC := '1'; + wren : IN STD_LOGIC := '0'; + q : OUT STD_LOGIC_VECTOR (3 DOWNTO 0) + ); +END component; + +signal out_addr : std_logic_vector(9 downto 0); +signal in_addr : std_logic_vector(9 downto 0); + +signal in_data : std_logic_vector(3 downto 0); +signal out_data : std_logic_vector(3 downto 0); +signal old_hs: std_logic; + +begin + + in_data(3) <= HS_IN; + in_data(2) <= R_IN; + in_data(1) <= G_IN; + in_data(0) <= B_IN; + + line_buffer_inst : line_buffer PORT MAP ( + wrclock => CLOCK, + wrclocken => CLKEN, + wren => '1', + data => in_data, + wraddress => in_addr, + + rdclock => CLOCK, + rdclocken => '1', + q => out_data, + rdaddress => out_addr + ); + + HS_OUT <= out_data(3); + R_OUT <= out_data(2); + G_OUT <= out_data(1); + B_OUT <= out_data(0); + VS_OUT <= VS_IN; + + process(CLOCK,CLKEN,nRESET,HS_IN,in_addr,out_addr) + begin + if nRESET = '0' then + in_addr <= (others => '0'); + out_addr <= (others => '0'); + elsif rising_edge(CLOCK) then + old_hs <= HS_IN; + + if old_hs ='0' and HS_IN='1' then + in_addr <= (others => '0'); + out_addr <= (others => '0'); + else + out_addr <= std_logic_vector(unsigned(out_addr) +1 ); + if CLKEN = '1' then + in_addr <= std_logic_vector(unsigned(in_addr) +1 ); + end if; + end if; + end if; + end process; +end architecture; +